home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.004 / xemacs-1 / xemacs-19.13 / lisp / packages / mode-motion+.el < prev    next >
Encoding:
Text File  |  1995-08-22  |  78.2 KB  |  2,197 lines

  1. ;;   -*- Syntax: Emacs-Lisp; Mode: emacs-lisp -*-
  2. ;;
  3. ;; Per mode and per buffer mouse tracking with highlighting
  4. ;;
  5. ;; Copyright (C) 1992, 1993 by Guido Bosch <Guido.Bosch@loria.fr>
  6.  
  7. ;; This file is written in GNU Emacs Lisp, It is a part of XEmacs.
  8.  
  9. ;; The software contained in this file is free software; you can
  10. ;; redistribute it and/or modify it under the terms of the GNU General
  11. ;; Public License as published by the Free Software Foundation; either
  12. ;; version 2, or (at your option) any later version.
  13.  
  14. ;; GNU Emacs is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ;; GNU General Public License for more details.
  18.  
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  21. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22. ;;
  23. ;; Please send bugs and comments to Russell.Ritchie@gssec.bt.co.uk or
  24. ;;                                  tlp00@spg.amdahl.com.
  25. ;;
  26. ;; <DISCLAIMER>
  27. ;; This program is still under development.  Neither the author nor any
  28. ;; of the maintainers accepts responsibility to anyone for the consequences of
  29. ;; using it or for whether it serves any particular purpose or works
  30. ;; at all.
  31.  
  32. ; Change History
  33. ; Revision 3.12 Wed Jul 12 11:30:43 1995 Russell.Ritchie@gssec.bt.co.uk
  34. ; Track `don't highlight non-file lines in dired buffers' functionality (in a
  35. ; pretty tasteless manner if I say so myself :-)).
  36.  
  37. ; Revision 3.11 Fri Jul  7 16:26:56 1995 Russell.Ritchie@gssec.bt.co.uk
  38. ; Minor extent detaching bug fix.
  39.  
  40. ; Revision 3.10 Thu Jun 15 11:36:56 1995 Russell.Ritchie@gssec.bt.co.uk
  41. ; Quiet, faster, non-interactive initialistion, mild list-motion-handlers
  42. ; chrome and minor formatting clean-ups.
  43.  
  44. ; Revision 3.9 Thu Jun 15 11:36:56 1995 Russell.Ritchie@gssec.bt.co.uk
  45. ; Fixed the `mouse-motion whilst reading filename in minibuffer auto-ftp' bug.
  46.  
  47. ; Revision 3.8 Thus Mar 23 1995 tlp00@spg.amdahl.com
  48. ; added in menu controls from paquette@atomas.crim.ca
  49. ; re-added minibuffer support (from 3.5)
  50. ;
  51. ; Revision 3.7 Tue Feb 21 11:06:38 1995 Russell.Ritchie@gssec.bt.co.uk
  52. ; Extended mode-motion+-religion and made the defaulting frame-buffer aware.
  53. ; Reworked and added new mode-motion-handlers.
  54. ; Doc string clean up.
  55. ; Fixed unintentional frame/screen reversion.
  56.  
  57. ; Revision 3.6 Mon Feb 20 11:46:32 1995 Russell.Ritchie@gssec.bt.co.uk
  58. ; Made mouse tracking use mode-motion-hook for better integration with
  59. ; the default mouse-motion system (help-echo and friends now work).
  60.  
  61. ; Revision 3.5 1995/02/16 13:40:00 tlp00@spg.amdahl.com
  62. ; fixed sporatic scroll bug
  63. ; added M-button2 binding for mode-motion-copy
  64. ;
  65. ; Revision 3.4 1995/02/14 14:30:15 Russell.Ritchie@gssec.bt.co.uk
  66. ; Small code cleanups: let* -> let, duplicate defvars.
  67. ; Chromed list-motion-handlers a little.
  68. ; Added variable mode-motion+-religion for easy choice twixt underline & bold.
  69.  
  70. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;tlp00 changes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  71.  
  72. ; tlp00@spg.amdahl.com 2/11/93
  73. ; modified mode-motion-track-pointer to move cursor cross windows
  74. ;          renamed mode-motion-delete to mode-motion-kill to follow kill
  75. ;            convention
  76. ;          mode-motion-highlight-with-handler to put cursor at beginning of line 
  77. ;            follow operations.
  78. ;          mode-motion-copy/delete and mode-motion-kill to position cursor at 
  79. ;            delete point start.  Also set this-command to avoid appends
  80. ; set mode-motion-extent priority to 1, so it will override font-lock
  81. ; changed default handlers for buffer-mode, c-mode, dired-mode, added occur 
  82. ;   and compilation mode.
  83. ; fixed bug in minibuffer-selection-boundaries where C-g was leaving the wrong
  84. ;   syntax table.
  85. ; added support for pending-delete.
  86. ; adds the copy/delete motion-extent to the clipboard even if kill-hooks is nil.
  87. ;
  88. ; Revision 3.3 1995/02/13 tlp00@spg.amdahl.com
  89. ; merged Russell.Ritchie@gssec.bt.co.uk versions with molli/bosch versions
  90. ; renamed versioning 3.0+ for molli/bosch versions.  
  91. ;
  92. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Russell Ritchie changes;;;;;;;;;;;;;;;;;;;;;;;;
  93. ; !Log: mode-motion+.el,v !
  94. ; Revision 2.14.R  1994/09/09  10:19:18  rieke@darmstadt.gmd.de
  95. ; Merged in my changes to support motion-gray. This needs a file
  96. ; named "gray1.xbm" in your data-directory (etc) like the following.
  97. ; -------------------------------snip--------------------------
  98. ; #define bg2_width 16
  99. ; #define bg2_height 16
  100. ; static char bg2_bits[] = {
  101. ;   0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
  102. ;   0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
  103. ;   0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00};
  104. ; -------------------------------snip--------------------------
  105. ; This one looks good on SUN 19'' screens with 10x20 font, 
  106. ; black foreground and khaki background. 
  107. ; To use the gray-handlers instead of the underline-handlers
  108. ; include the following into your .emacs:
  109. ; (set-mode-motion-handler 'emacs-lisp-mode 'gray-thing)
  110. ; (set-mode-motion-handler 'lisp-interaction-mode 'gray-thing)
  111. ; (set-mode-motion-handler 'c++-mode 'gray-c)
  112. ; (set-mode-motion-handler 'c-mode 'gray-c)
  113. ; (set-mode-motion-handler 'tcl-mode 'gray-tcl)
  114. ; (set-mode-motion-handler 'dired-mode 'gray-line@)
  115. ; (set-mode-motion-handler 'gnus-group-mode 'gray-vline@)
  116. ; (set-mode-motion-handler 'gnus-summary-mode 'gray-vline@)
  117. ; (set-mode-motion-handler 'texinfo-mode 'gray-Texinfo)
  118. ; (setq default-motion-handler (find-motion-handler 'gray-thing))
  119. ;
  120. ;
  121. ; Revision 2.13.R  1994/08/08  19:47:34  Russell.Ritchie@gssec.bt.co.uk
  122. ; Made default handler be underline-thing, as most bold fonts seem to
  123. ; be greater in height than their corresponding normal versions,
  124. ; causing irritating screen flicker.
  125. ;
  126. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Molli/bosch changes;;;;;;;;;;;;;;;;;;;;;;;;
  127. ;
  128. ; Revision 3.2  1994/09/28  15:14:29  molli
  129. ; add   "(set-mode-motion-handler 'latex-mode   'raise-LaTeX)".    Barry
  130. ; Waraw's C/C++ mode is now changed to cc-mode ...
  131. ;
  132. ; Revision 3.1  1994/09/28  15:10:36  molli
  133. ; Initial revision
  134. ;
  135. ; Revision 2.15  1993/11/18  08:13:28  bosch
  136. ; Constant `mode-motion+-version' added.
  137. ; Minor bug fix in `tcl-forward-sexp1'.
  138. ;
  139. ; Revision 2.14  1993/10/29  20:04:59  bosch
  140. ; Minibuffer name matching improved.  Made `tcl-boundaries' smarter by
  141. ; use of new function `tcl-forward-sexp1'. `tcl-commands' list updated
  142. ; -- should be complete now.  A message is printed if the syntax scanner
  143. ; matched or failed for known tcl/tk commands.  Seperated `tcl-commands'
  144. ; from `tk-commands' -- `tk-commands' not yet complete.  New motion
  145. ; handler `raise-LaTeX' added, for tex-mode.
  146. ;
  147. ; Revision 2.13  1993/10/08  09:43:00  bosch
  148. ; New user option `mode-motion-setup-cut-and-paste-bindings'.  Function
  149. ; `mode-motion-copy/delete' now takes into account the primary and the
  150. ; motion selection.
  151. ;
  152. ; Revision 2.12  1993/10/08  09:08:46  bosch
  153. ; Avoid highlighting empty lines, even if
  154. ; `mode-motion-highlight-lines-when-behind' is non-nil.
  155.  
  156. ; Revision 2.12  1994/07/07  18:33:38  Russell.Ritchie@gssec.bt.co.uk
  157. ; Made list-motion-handlers and mode-motion-set-handler work in lemacs-19.10.
  158. ; Revision 2.11  1993/09/20  08:29:15  bosch
  159. ; Code reorganized: variables declared before used.
  160. ; Compatibility hack patched again.
  161. ;
  162. ; Revision 2.10  1993/09/17  18:50:33  bosch
  163. ; Bug in the compatibility hack fixed. Call to `make-cursor' replaced by
  164. ; `x-pointer-cache'. Compatibility hack for Lemacs 19.8 removed.  Tcl
  165. ; motion handler improved (needs still some work).
  166. ;
  167. ; Revision 2.9  1993/09/15  17:52:53  bosch
  168. ; Compatibility patch for Lucid Emacs 19.8. tcl motion handler added.
  169. ;
  170. ; Revision 2.8  1993/08/27  15:17:07  bosch
  171. ; Select window conflict between motion handlers and process filters
  172. ; resolved by using `enqueue-eval-event' for selecting a different
  173. ; window (functions `mode-motion-track-pointer' and
  174. ; `mode-motion-highlight-with-handler' modified). This fixes the nasty
  175. ; bug that made GNUS hanging during NNTP activity while the mouse was
  176. ; moved.
  177. ;
  178. ; Revision 2.7  1993/08/27  12:50:10  bosch
  179. ; TeX and LaTeX motion handler generalized.  Motion handler
  180. ; `highlight-Texinfo' added.
  181. ;
  182. ; Revision 2.6  1993/06/24  11:58:52  bosch
  183. ; Mode motion+ support for pcl-cvs added. #undef syntax for C added.
  184. ;
  185. ; Revision 2.5  1993/06/09  12:04:31  bosch
  186. ; Delivery motion handlers for `c++-c-mode', `gnus-group-mode', and
  187. ; `gnus-summary-mode' added. Mode motion commands bound to copy/cut/past
  188. ; keys for Sun keyboards (f16, f18, f20). Comment added.
  189. ;
  190. ; Revision 2.4  1993/02/15  12:59:47  bosch
  191. ; Modifications sent by Tibor Polgar integrated:
  192. ; Optional parameter added to `mode-motion-copy/delete'.  User option
  193. ; `mode-motion-focus-on-window' added. It controls window selection for
  194. ; the motion handlers. Minor changes of the delivery motion handlers.
  195. ;
  196. ; Revision 2.3  1993/02/04  18:10:09  bosch
  197. ; User option `mode-motion-minibuffer-completion' added. It controls
  198. ; the minibuffer completion highlighting.
  199. ;
  200. ; Revision 2.2  1993/01/27  13:08:12  bosch
  201. ; Improved clearing of `sticky' mode-motion-extents when leaving screen
  202. ; or buffer.  Function `mode-motion-clear-extent' added.
  203. ; Highlight line mouse cursor is behind.
  204. ; `mode-motion-highlight-with-handler' now takes an event as argument.
  205. ; Cut and paste functions renamed and rewritten. Now they are called:
  206. ; `mode-motion-move', `mode-motion-delete', `mode-motion-copy',
  207. ; `mode-motion-copy-as-kill'.  Bug fixes in the C scanner stuff.
  208. ; Motion handler `underline-c' added.
  209. ;
  210. ; Revision 2.1  1993/01/19  18:29:58  bosch
  211. ; Scanner and motion handler for C syntax added.
  212. ; Function `set-default-motion-handler' added.
  213. ; Minor improvements on the `list-motion-handlers' interface done.
  214. ; Minor bug fixes.
  215. ;
  216. ; Revision 2.0 1993/01/14   19:17:29  bosch
  217. ; Lot of things rewritten and reorganized. This version fits in only
  218. ; one file (beside the required package thing.el).
  219. ;
  220. ; New basic features are:
  221. ;  - buffer, mode and default motion handlers
  222. ;  - easy composition of own motion handlers
  223. ;  - listing of motion handlers in tabular form
  224. ;  - menu interface for changing motion handlers
  225. ;  - only two  elisp files: mode-motion+.el, thing.el
  226.  
  227. (require 'thing)
  228. (require 'mode-motion)
  229. (defconst mode-motion+-version "3.12")
  230.  
  231. ;;; This file defines a set of mouse motion handlers that do some
  232. ;;; highlighting of the text when the mouse moves over.
  233. ;;; An exhaustive list of the motion handlers defined in this file may be
  234. ;;; obtained with M-x list-motion-handlers.
  235. ;;; User Options and their Custommisation
  236. ;;;
  237. ;;; Mode-motion+ provides four user options, defined beyond. See their
  238. ;;; documentation string to know what they are good for. If you want
  239. ;;; to modify their default values, just setq them in your ~/.emacs.
  240.  
  241. (defvar mode-motion+-religion nil ; Initialised in mode-motion-init.
  242.   "*Default highlight religion: one of bold, gray, highlight, invert or underline.
  243.  
  244. Unless you setq this otherwise, it defaults to underline when
  245. (x-display-color-p) is non-nil and invert otherwise.
  246. Setting it to 'highlight should cause mode-motion+ extents to be
  247. indistinguishable from any other type of highlighted extent which may or may
  248. not be advisable, depending on your point of view.")
  249.  
  250. (defvar mode-motion-highlight-lines-when-behind t
  251.   "*If non-nil highlight the whole line if the mouse is past the end.")
  252.  
  253. (defvar mode-motion-focus-on-window 'follow-point
  254.   "*Controls whether moving the mouse into another window selects this window.
  255. The following values are possible:
  256.  
  257. nil      - Window selection isn't influenced at all by mode motion.
  258.  
  259. t      - Window selection always follows the mouse cursor. Copying
  260.         motion active regions doesn't work any longer between
  261.         different buffers.
  262.         
  263. any other - \(the default\) Window selection follows the mouse cursor if
  264.         the motion handler of the buffer under the mouse has the
  265.         follow-point property set. Useful for selecting line mode
  266.         buffers just by moving the mouse inside in order to
  267.         execute commands there. \(VM summary, GNUS Group and
  268.         Subject , DIRED, Buffer menu etc.\) 
  269.         Be aware: GNUS blocks with this option set when moving the 
  270.         mouse while retrieving headers or articles via the NNTP
  271.         service.")
  272.  
  273. (defvar mode-motion-setup-cut-and-paste-bindings t
  274.   "*If non-nil, bind commands to the Copy, Paste and Cut keys.")
  275.  
  276. ;;  Options sub-menu for mode-motion+
  277. (defvar mode-motion+-options-menu 
  278.   '("Motion Highlighting"
  279.     "For Current Buffer"
  280.     "---"
  281.     ["None"
  282.      (progn
  283.        (set-buffer-motion-handler (current-buffer) 'no-thing)
  284.        (mode-motion-clear-extent))
  285.      :style radio
  286.      :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
  287.            'no)
  288.      :active (mode-motion+-active-p)]
  289.     ["Bold"
  290.      (progn
  291.        (modify-buffer-motion-handler (current-buffer) 'bold))
  292.      :style radio
  293.      :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
  294.            'bold)
  295.      :active (mode-motion+-active-p)]
  296.     ["Underline"
  297.      (progn
  298.        (modify-buffer-motion-handler (current-buffer) 'underline))
  299.      :style radio
  300.      :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
  301.            'underline)
  302.      :active (mode-motion+-active-p)]
  303.     ["Gray"
  304.      (progn
  305.        (modify-buffer-motion-handler (current-buffer) 'gray))
  306.      :style radio
  307.      :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
  308.            'gray)
  309.      :active (mode-motion+-active-p)]
  310.     ["Highlight"
  311.      (progn
  312.        (modify-buffer-motion-handler (current-buffer) 'highlight))
  313.      :style radio
  314.      :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
  315.            'highlight)
  316.      :active (mode-motion+-active-p)]
  317.     ["Invert"
  318.      (progn
  319.        (modify-buffer-motion-handler (current-buffer) 'invert))
  320.      :style radio
  321.      :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
  322.            'invert)
  323.      :active (mode-motion+-active-p)]
  324.     "---"
  325.     "For Current Mode"
  326.     "---"
  327.     ["None"
  328.      (progn
  329.        (set-mode-motion-handler major-mode 'no-thing)
  330.        (mode-motion-clear-extent))
  331.      :style radio
  332.      :selected (eq (mode-motion+-mode-handler-religion major-mode) 'no)
  333.      :active (mode-motion+-active-p)]
  334.     ["Bold"
  335.      (progn
  336.        (modify-mode-motion-handler major-mode 'bold))
  337.      :style radio
  338.      :selected (eq (mode-motion+-mode-handler-religion major-mode) 'bold)
  339.      :active (mode-motion+-active-p)]
  340.     ["Underline"
  341.      (progn
  342.        (modify-mode-motion-handler major-mode 'underline))
  343.      :style radio
  344.      :selected (eq (mode-motion+-mode-handler-religion major-mode) 'underline)
  345.      :active (mode-motion+-active-p)]
  346.     ["Gray"
  347.      (progn
  348.        (modify-mode-motion-handler major-mode 'gray))
  349.      :style radio
  350.      :selected (eq (mode-motion+-mode-handler-religion major-mode) 'gray)
  351.      :active (mode-motion+-active-p)]
  352.     ["Highlight"
  353.      (progn
  354.        (modify-mode-motion-handler major-mode 'highlight))
  355.      :style radio
  356.      :selected (eq (mode-motion+-mode-handler-religion major-mode) 'highlight)
  357.      :active (mode-motion+-active-p)]
  358.     ["Invert"
  359.      (progn
  360.        (modify-mode-motion-handler major-mode 'invert))
  361.      :style radio
  362.      :selected (eq (mode-motion+-mode-handler-religion major-mode) 'invert)
  363.      :active (mode-motion+-active-p)]
  364.     "---"
  365.     "For All"
  366.     "---"
  367.     ["None"
  368.      (progn
  369.        (setq mode-motion+-religion 'no)
  370.        (mode-motion-init-handlers-according-to-religion 'force)
  371.        (mode-motion-clear-extent))
  372.      :style radio
  373.      :selected (eq mode-motion+-religion 'no)
  374.      :active (mode-motion+-active-p)]
  375.     ["Bold"
  376.      (progn
  377.        (setq mode-motion+-religion 'bold)
  378.        (mode-motion-init-handlers-according-to-religion 'force))
  379.      :style radio
  380.      :selected (eq mode-motion+-religion 'bold)
  381.      :active (mode-motion+-active-p)]
  382.     ["Underline"
  383.      (progn
  384.        (setq mode-motion+-religion 'underline)
  385.        (mode-motion-init-handlers-according-to-religion 'force))
  386.      :style radio
  387.      :selected (eq mode-motion+-religion 'underline)
  388.      :active (mode-motion+-active-p)]
  389.     ["Gray"
  390.      (progn
  391.        (setq mode-motion+-religion 'gray)
  392.        (mode-motion-init-handlers-according-to-religion 'force))
  393.      :style radio
  394.      :selected (eq mode-motion+-religion 'gray)
  395.      :active (mode-motion+-active-p)]
  396.     ["Highlight"
  397.      (progn
  398.        (setq mode-motion+-religion 'highlight)
  399.        (mode-motion-init-handlers-according-to-religion 'force))
  400.      :style radio
  401.      :selected (eq mode-motion+-religion 'highlight)
  402.      :active (mode-motion+-active-p)]
  403.     ["Invert"
  404.      (progn
  405.        (setq mode-motion+-religion 'invert)
  406.        (mode-motion-init-handlers-according-to-religion 'force))
  407.      :style radio
  408.      :selected (eq mode-motion+-religion 'invert)
  409.      :active (mode-motion+-active-p)]
  410.     "---"
  411.     ["Minibuffer highlighting" (setq mode-motion-use-minibuffer-motion-handler
  412.                      (not mode-motion-use-minibuffer-motion-handler))
  413.      :style toggle :selected mode-motion-use-minibuffer-motion-handler]
  414.      
  415.     ["Customize..."
  416.      (list-motion-handlers)
  417.      t
  418.      ;;     nil
  419.      ]
  420.      ["Revert Customization"
  421.      (call-interactively 'mode-motion+-motion-hook-revert)
  422.      (and (boundp 'mode-motion+-previous-hook) mode-motion+-previous-hook)
  423.      ])
  424.   "Menu for changing mode-motion+ religion and other things.")
  425.  
  426. (defun mode-motion+-active-p ()
  427.   (cond ((symbolp mode-motion-hook)
  428.      (eq mode-motion-hook 'mode-motion+-highlight))
  429.     ((listp mode-motion-hook)
  430.      (memq 'mode-motion+-highlight mode-motion-hook))
  431.     (t nil)))
  432.      
  433. (defun mode-motion+-buffer-handler-religion (buffer)
  434.   (let* ((current-handler-name (symbol-name (motion-handler-name
  435.                          (get-current-motion-handler))))
  436.      (religion-name (substring current-handler-name
  437.                    0
  438.                    (string-match "-" current-handler-name))))
  439.     (intern-soft religion-name)))
  440.  
  441. (defun mode-motion+-mode-handler-religion (buffer)
  442.   (let* ((mode-handler (or (get major-mode 'mode-motion-handler)
  443.                default-motion-handler))
  444.      (current-handler (symbol-name (motion-handler-name mode-handler)))
  445.      (religion (substring current-handler
  446.                   0
  447.                   (string-match "-" current-handler))))
  448.     (intern-soft religion)))
  449.  
  450. (defun modify-buffer-motion-handler (buffer religion)
  451.   (let* ((current-handler (symbol-name (motion-handler-name
  452.                          (get-current-motion-handler))))
  453.      (suffix (substring current-handler
  454.                 (string-match "-" current-handler))))
  455.     (set-buffer-motion-handler buffer
  456.                    (intern-soft (concat (symbol-name religion)
  457.                             suffix)))))
  458.  
  459. (defun modify-mode-motion-handler (mode religion)
  460.   (let* ((mode-handler (or (get major-mode 'mode-motion-handler)
  461.                default-motion-handler))
  462.      (current-handler (symbol-name (motion-handler-name mode-handler)))
  463.      (suffix (substring current-handler
  464.                 (string-match "-" current-handler))))
  465.     (set-mode-motion-handler mode (intern-soft (concat (symbol-name
  466.                             religion)
  467.                                suffix)))))
  468.  
  469. ;;;; This does not work.  I would like to be able to modify in-place
  470. ;;;; the non-selectable items, but I don't know how.
  471. ;;;; --paquette, Wed Mar  8 23:32:32 1995 (Marc Paquette) 
  472. ;;; Sensitize the mode motion+ options submenu, a la
  473. ;;; sensitize-file-and-edit-menus-hook.
  474. (defun mode-motion+-sensitize-options-menu-hook ()
  475.   "Hook function that will adjust title items in the mode-motion+ submenu in Options"
  476.   (let* ((mm+-menu (cdr (car (find-menu-item
  477.                   current-menubar
  478.                   '("Options" "Motion Highlighting")))))
  479.      (buffer-item (find-menu-item mm+-menu '("For Current Buffer")))
  480.      (mode-item (find-menu-item mm+-menu '("For Current Mode"))))
  481.     (setcar buffer-item (format "For Buffer `%s'" (buffer-name nil)))
  482.     (setcar mode-item (format "For Mode `%s'" major-mode))
  483.     nil))
  484.  
  485. ;;(add-hook 'activate-menubar-hook 'mode-motion+-sensitize-options-menu-hook)
  486.   
  487.  
  488. ;;  Motion Handler Format:
  489. ;;      
  490. ;; A motion handler is vector with the following format 
  491. ;; [<name>                    - a symbol
  492. ;;  <region computing function> - a function or name of function 
  493. ;;                  that returns (<startpos> . <endpos>) 
  494. ;;                  or nil.
  495. ;;  <face or face name>        - as it says ...
  496. ;;  <highlight-p>        - non-nil means that the motion extent
  497. ;;                  will be highlighted using the function 
  498. ;;                  `highlight-extent'
  499. ;;  <follow-point-p>        - non-nil means that point will follow the
  500. ;;                  mouse motion. 
  501. ;; ]
  502.  
  503. ;; accessor functions
  504. (defsubst motion-handler-name (handler) (aref handler 0))
  505. (defsubst motion-handler-boundary-function (handler) (aref handler 1))
  506. (defsubst motion-handler-face (handler) (aref handler 2))
  507. (defsubst motion-handler-highlight (handler) (aref handler 3))
  508. (defsubst motion-handler-follow-point (handler) (aref handler 4))
  509.  
  510. ;; modifier functions
  511. (defsubst set-motion-handler-boundary-function (handler x) (aset handler 1 x))
  512. (defsubst set-motion-handler-face (handler x) (aset handler 2 x))
  513. (defsubst set-motion-handler-highlight (handler x) (aset handler 3 x))
  514. (defsubst set-motion-handler-follow-point (handler x) (aset handler 4 x))
  515.  
  516. ;; Internal global variables 
  517. (defvar motion-handler-alist ()
  518.   "Alist with entries of the form \(<name> . <handler>\).")
  519.  
  520. ;; Minibuffer motion handler
  521. (defvar mode-motion-use-minibuffer-motion-handler t
  522.   "*Enable mousable highlighting when the minibuffer is active. When false only extents with the
  523. highlight property are selectable (*Completion*)")
  524.  
  525. (defvar mode-motion-extent nil)
  526. (make-variable-buffer-local 'mode-motion-extent)
  527. (defvar buffer-motion-handler nil)
  528. (make-variable-buffer-local 'buffer-motion-handler)
  529. (defvar mode-motion-last-extent nil "The last used mode motion extent.")
  530. (defvar default-motion-handler nil)    ; Initialised in mode-motion-init.
  531.  
  532. ;; Creation of motion handlers
  533.  
  534. (defun find-motion-handler (name)
  535.   (or (symbolp name)
  536.       (setq name (intern-soft name)))
  537.   (cdr (assq name motion-handler-alist)))
  538.  
  539. ;; internal motion handler creator
  540. (defsubst make-motion-handler-internal 
  541.   (name boundary-function face highlight follow-cursor)
  542.   (vector name boundary-function (get-face face) highlight follow-cursor))
  543.  
  544. (defun make-motion-handler 
  545.   (name boundary-function &optional face highlight follow-cursor)
  546.   "Create a motion handler named NAME (a symbol or string) using REGION-FUNCTION.
  547.  
  548. REGION-FUNCTION is the function that computes the region to be highlighted. 
  549. Optional arguments are: 
  550.  
  551. FACE: A face or face name to be used to highlight the region computed
  552.       by REGION-FUNCTION.  'default is the default.
  553.       
  554. HIGHLIGHT: Flag that indicates whether the highlight attribute of the
  555.       mode-motion-extent should be set or not. If FACE is the default face, 
  556.       HIGHLIGHT defaults to t, otherwise to nil.
  557.  
  558. FOLLOW-CURSOR: Flag that indicates whether the cursor should follow
  559.       the mouse motion. Default is nil."
  560.  
  561.   ;; required arguments
  562.   (or name (error "motion handler name required."))
  563.   (or (symbolp name) 
  564.       (stringp name)
  565.       (error "motion handler name must be a string or symbol: %s" name))
  566.   (or boundary-function 
  567.       (error "motion handler region function required."))
  568.   (or (fboundp boundary-function)
  569.       (error "not a function: %s." boundary-function))
  570.   ;; defaults
  571.   (or face (setq face 'default))
  572.   
  573.   ;; store the mode motion handler on the 'mode-motion-handler property of
  574.   ;; its name symbol
  575.   (let ((old-handler (cdr (assq name motion-handler-alist)))
  576.     new-handler)
  577.     (if old-handler
  578.     (progn 
  579.       (set-motion-handler-boundary-function old-handler boundary-function)
  580.       (set-motion-handler-face old-handler (get-face face))
  581.       (set-motion-handler-highlight old-handler highlight)
  582.       (set-motion-handler-follow-point old-handler follow-cursor))
  583.       (setq motion-handler-alist 
  584.         (cons (cons name 
  585.             (setq new-handler (make-motion-handler-internal
  586.                        name
  587.                        boundary-function
  588.                        (get-face face)
  589.                        highlight
  590.                        follow-cursor)))
  591.           motion-handler-alist)))
  592.     (or old-handler new-handler)))
  593.  
  594. (defvar list-motion-handlers-buffer-to-customize nil
  595.   "Name of buffer from where list-motion-handlers was called.")
  596. (make-variable-buffer-local 'list-motion-handlers-buffer-to-customize)
  597. (defvar list-motion-handlers-buffer-mode nil
  598.   "Name of mode of buffer from where list-motion-handlers was called.")
  599. (make-variable-buffer-local 'list-motion-handlers-buffer-mode)
  600. ;; Listing available motion handlers in tabular form. 
  601.       
  602. (defvar basic-motion-handlers (list 'mode-motion-highlight-line
  603.                     'mode-motion-highlight-word
  604.                     'mode-motion-highlight-symbol
  605.                     'mode-motion-highlight-sexp)
  606.   "The basic motion handlers provided by the underlying XEmacs.")
  607.  
  608. (defun list-motion-handlers ()
  609.   "Display a list of available motion handlers.
  610. The listing is in tabular form and contains the following columns:
  611. NAME: the motion handlers name,
  612. BOUNDARY FUNCTION: the name of the funtion used to compute the text  
  613.    highlighted by the motion handler,
  614. FACE: the face used to highlight the text.
  615.  
  616. Additionally, the following flags are used at the beginning of each line:
  617. `*' Marks the motion handler current to the buffer this functions was called 
  618.     from.
  619. `H' Force highlighting of the selected text.
  620. `F' Make point follow the mouse cursor as it moves."
  621.   (interactive)
  622.   (let ((current-handler (get-current-motion-handler))
  623.     (buffer (current-buffer))
  624.     (buffer-mode major-mode)
  625.     (bmmh (if (symbolp mode-motion-hook)
  626.           (car (memq mode-motion-hook basic-motion-handlers))
  627.         (if (and (listp mode-motion-hook) 
  628.              (equal 1 (length mode-motion-hook)))
  629.             (car (memq (car mode-motion-hook)
  630.                    basic-motion-handlers))))))
  631.     (save-excursion
  632.       (with-output-to-temp-buffer "*Mouse Motion Handlers*"
  633.     (let ((truncate-lines t))
  634.       (set-buffer "*Mouse Motion Handlers*")
  635.       (setq list-motion-handlers-buffer-to-customize buffer)
  636.       (setq list-motion-handlers-buffer-mode buffer-mode)
  637.       (let ((pos1 5)
  638.         (pos2 25)
  639.         (pos3 50)
  640.         (handlers 
  641.          (sort 
  642.           (mapcar 'cdr motion-handler-alist)
  643.           '(lambda (x y)
  644.              (string<
  645.               (symbol-name (motion-handler-boundary-function x))
  646.               (symbol-name (motion-handler-boundary-function y)))))))
  647.         (if bmmh
  648.         (let ((i 1)
  649.               (fw (frame-width)))
  650.           (while (< i fw)
  651.             (princ "*")
  652.             (setq i (1+ i)))
  653.           (princ "\nNote: this buffer is not using mode-motion+.\n\n")
  654.           (princ "It's using the `")
  655.           (princ bmmh)
  656.           (princ "' motion handler which claims it's:\n")
  657.           (insert (documentation bmmh))
  658.           (princ "\nSetting this motion handler will be irrevocable from this interface\n(but only for duration of this XEmacs session).\n")
  659.           (setq i 1)
  660.           (while (< i fw)
  661.             (princ "*")
  662.             (setq i (1+ i)))
  663.           (terpri)))
  664.         (princ "     NAME                BOUNDARY FUNCTION        FACE\n")
  665.         (princ "     ----                -----------------        ----\n")
  666.         (mapcar 
  667.          #'(lambda (handler)
  668.          (let ((line-start (point)))
  669.            (princ (if (and (not bmmh) (eq handler current-handler))
  670.                   "*" " "))
  671.            (princ (if (eq handler default-motion-handler) "D" " "))
  672.            (princ (if (motion-handler-highlight handler) "H" " "))
  673.            (princ (if (motion-handler-follow-point handler) "F" " "))
  674.            (indent-to-column pos1 1)
  675.            (princ (motion-handler-name handler))
  676.            (indent-to-column pos2 1)
  677.            (princ (motion-handler-boundary-function handler))
  678.            (indent-to-column pos3)
  679.            (let ((face-start (point)))
  680.              (princ (face-name (motion-handler-face handler)))
  681.              (let ((line-extent (make-extent line-start face-start))
  682.                (face-extent (make-extent face-start (point))))
  683.              (set-extent-face face-extent
  684.                       (motion-handler-face handler))
  685.              (set-extent-property
  686.               face-extent
  687.               'mode-motion-handler (motion-handler-name handler))
  688.              (set-extent-property
  689.               line-extent
  690.               'mode-motion-handler (motion-handler-name handler))
  691.              (set-extent-property line-extent 'highlight t)))
  692.          (terpri)))
  693.          handlers)
  694.         (princ (format "
  695. Flags:    `D' the default motion handler
  696.            `H' handler with highlighting
  697.     `F' handler with `following' property
  698.     `*' the motion handler of buffer \"%s\""
  699.                list-motion-handlers-buffer-to-customize))))
  700.     (local-set-key 'button3 'mode-motion-set-handler)
  701.     (setq buffer-read-only t)))))
  702.  
  703. (defun mode-motion-set-handler (event)
  704.   (interactive "@e")
  705.   (let* ((handler (or (extent-property
  706.                (extent-at (event-point event) (current-buffer)
  707.                   'mode-motion-handler)
  708.                'mode-motion-handler)
  709.               (error "Click on highlighted line to select a handler")))
  710.      (menu (list
  711.         (format "Make `%s' the Motion Handler of :" handler)
  712.         (vector (format "Buffer %s"
  713.                 list-motion-handlers-buffer-to-customize)
  714.             (` (set-buffer-motion-handler
  715.                 '(, list-motion-handlers-buffer-to-customize)
  716.                 '(, handler))) t)
  717.         (vector "Another Buffer..."
  718.             (` (motion-handler-list-set-buffer-handler
  719.                 '(, handler))) t)
  720.         "---"
  721.         (vector (format "Mode %s"
  722.                 list-motion-handlers-buffer-mode)
  723.             (` (progn
  724.                  (set-mode-motion-handler
  725.                   '(, list-motion-handlers-buffer-mode)
  726.                   '(, handler))
  727.                  (save-excursion
  728.                    (mapcar
  729.                 (function
  730.                  (lambda (buf)
  731.                    (set-buffer buf)
  732.                    (and (eq
  733.                      '(, list-motion-handlers-buffer-mode)
  734.                      major-mode)
  735.                     (mode-motion+-hook-install buf t))))
  736.                        (buffer-list))))) t)
  737.         (vector "Another Mode..."
  738.             (` (motion-handler-list-set-mode-handler
  739.                 '(, handler))) t)
  740.         "---"
  741.         (vector "Default Motion Handler"
  742.             (` (set-default-motion-handler '(, handler))) t))))
  743.     (popup-menu menu)))
  744.  
  745. (defun motion-handler-list-set-buffer-handler (handler)
  746.   (let ((buffer (read-buffer-name 
  747.          (format "Make `%s' the motion handler of buffer: " handler)
  748.          (buffer-name list-motion-handlers-buffer-to-customize))))
  749.     (set-buffer-motion-handler buffer handler)
  750.     (save-excursion
  751.       (set-buffer buffer)
  752.       (and (not (cond ((listp mode-motion-hook)
  753.                (memq 'mode-motion+-highlight mode-motion-hook))
  754.               ((symbolp mode-motion-hook)
  755.                (eq 'mode-motion+-highlight mode-motion-hook))
  756.               (t t)))
  757.        (y-or-n-p (format "Augment the default mode motion hook for `%s'? "
  758.                  (buffer-name nil)))
  759.        (mode-motion+-hook-install buffer t)))))
  760.  
  761. (defvar mode-motion+-previous-hook nil
  762.   "Value of previous `mode-motion-hook' in current buffer.")
  763. (make-variable-buffer-local 'mode-motion+-previous-hook)
  764.  
  765. (defun motion-handler-list-set-mode-handler (handler)
  766.   (let ((mode (intern (completing-read
  767.         (format "Make `%s' the motion handler of mode: " handler)
  768.         obarray
  769.         'fboundp
  770.         t    
  771.         (symbol-name list-motion-handlers-buffer-mode)))))
  772.     (set-mode-motion-handler mode handler)
  773.   (save-excursion
  774.     (mapcar (function
  775.          (lambda (buf)
  776.            (set-buffer buf)
  777.            (and (eq mode major-mode)
  778.             (mode-motion+-hook-install buf t))))
  779.         (buffer-list)))))
  780.  
  781. (defun mode-motion+-hook-install (&optional buffer remove-highlight-line-p)
  782.   "Add `mode-motion+-highlight' to the BUFFER `mode-motion-hook'.
  783. If the optional second arg REMOVE-HIGHLIGHT-LINE-P is t, remove
  784. `mode-motion-highlight-line' from `mode-motion-hook'.
  785. See `mode-motion+-hook-uninstall' for reverting this operation."
  786.   (interactive "bInstall mode-motion+ hook for buffer :
  787. XRemove highlight-line from hook ? :")
  788.   ;; Check for the mode-motion-hook value to make sure it's under
  789.   ;; the control of mode-motion+.
  790.   ;; The reasonning here is that if the user went trough the hassles
  791.   ;; of list-motion-handlers (or if he's calling this directly from
  792.   ;; his .emacs) , he is prepared to give up on the current
  793.   ;; mode-motion-hook.
  794.   ;; However, we keep the previous hook value in a buffer-local
  795.   ;; variable: it will be then possible to revert to the old motion
  796.   ;; handling behavior with `mode-motion+-hook-uninstall'.
  797.   ;; --paquette, Mon Feb 27 08:54:30 1995 (Marc Paquette)
  798.   (setq buffer (or buffer (current-buffer)))
  799.   ;; force the uninstall of mode-motion-highlight since if its second
  800.   ;; you'll never see ours.
  801.   (setq remove-highlight-line-p t)
  802.   (save-excursion
  803.     (set-buffer buffer)
  804.     (if (boundp 'mode-motion-hook)
  805.     (progn
  806.       (setq mode-motion+-previous-hook
  807.         (cond ((sequencep mode-motion-hook)
  808.                (copy-sequence mode-motion-hook))
  809.               (t mode-motion-hook)))
  810.       ;; Make sure that the mode-motion+-highlight is not saved in
  811.       ;; the variable, otherwise, we could not revert back to the
  812.       ;; "factory settings" after having played with different
  813.       ;; handlers
  814.       ;; --paquette, Mon Feb 27 08:54:21 1995 (Marc Paquette)
  815.       (remove-hook 'mode-motion+-previous-hook 'mode-motion+-highlight)))
  816.     (add-hook 'mode-motion-hook 'mode-motion+-highlight)
  817.     (and remove-highlight-line-p
  818.      ;; Remove the standard mode-motion-highlight hook because we
  819.      ;; provide an alternative to this.  I don't use setq here because
  820.      ;; something else could be hooked to mode-motion-hook.
  821.      ;; --paquette, Mon Feb 27 08:53:51 1995 (Marc Paquette)
  822.      (remove-hook 'mode-motion-hook 'mode-motion-highlight-line))
  823.     (and mode-motion-extent
  824.      (delete-extent mode-motion-extent)
  825.      (setq mode-motion-extent nil))
  826.     ;; Try to make this installed for any buffer of this mode
  827.     (let ((this-mode-hook (intern-soft (concat (symbol-name major-mode)
  828.                            "-hook"))))
  829.       (and (boundp this-mode-hook)
  830.        (if remove-highlight-line-p
  831.            (add-hook this-mode-hook
  832.              #'(lambda () (mode-motion+-hook-install nil t))
  833.              'append)
  834.          (add-hook this-mode-hook 'mode-motion+-hook-install 'append)))))
  835.   mode-motion-hook)
  836.  
  837. (defun mode-motion+-hook-uninstall (buffer)
  838.   "Restore the value of `mode-motion-hook' in BUFFER to what it was at the time `mode-motion+-hook-install' was called.
  839. See also `mode-motion+-hook-install'."
  840.   (interactive "bRestore `mode-motion-hook' of buffer :")
  841.   ;; Check for the mode-motion-hook value to make sure it's under
  842.   ;; the control of mode-motion+.
  843.   ;; The reasonning here is that if the user went trough the hassles
  844.   ;; of list-motion-handlers (or if he's calling this directly from
  845.   ;; his .emacs) , he is prepared to give up on the current
  846.   ;; mode-motion-hook.
  847.   ;; However, we keep the previous hook value in a buffer-local
  848.   ;; variable: it will be then possible to revert to the old motion
  849.   ;; handling behavior with `mode-motion+-hook-uninstall'.
  850.   ;; --paquette, Mon Feb 27 08:54:30 1995 (Marc Paquette)
  851.   (save-excursion
  852.     (set-buffer buffer)
  853.     (and mode-motion-extent
  854.      (delete-extent mode-motion-extent)
  855.      (setq mode-motion-extent nil))
  856.     (if (boundp 'mode-motion+-previous-hook)
  857.     (progn
  858.       (setq mode-motion-hook mode-motion+-previous-hook)
  859.       (setq mode-motion+-previous-hook nil)
  860.       (let ((this-mode-hook (intern-soft (concat (symbol-name major-mode)
  861.                              "-hook"))))
  862.         (and (boundp this-mode-hook)
  863.          (remove-hook this-mode-hook 'mode-motion+-hook-install))))
  864.       (error "No previous value for mode-motion-hook")))
  865.   mode-motion-hook)
  866.  
  867. (defun mode-motion+-motion-hook-revert (&optional buffer-only-p buffer mode)
  868.   "Revert the `mode-motion-hook' to its original value.
  869. With optional arg BUFFER-ONLY-P non-nil, only revert in BUFFER
  870. \(defaults to `\(current-buffer\)'\); otherwise, revert for all existing
  871. buffers of MODE \(defaults to `major-mode' of BUFFER\)."
  872.   (interactive
  873.     (let* ((buffer-only-p
  874.        (y-or-n-p "Revert mode-motion-hook only for current buffer ? "))
  875.        (buffer (if buffer-only-p
  876.                (current-buffer)
  877.              (get-buffer (read-buffer-name
  878.                   "Revert mode-motion-hook of buffer : "
  879.                   (buffer-name (current-buffer))))))
  880.        (mode (if buffer-only-p
  881.              (save-excursion
  882.                (set-buffer buffer)
  883.                major-mode)
  884.            (intern-soft (completing-read "Major mode: "
  885.                          obarray
  886.                          'fboundp    
  887.                          nil 
  888.                          (symbol-name major-mode))))))
  889.       (list buffer-only-p buffer mode)))
  890.   (if buffer-only-p
  891.       (mode-motion+-hook-uninstall buffer)
  892.     (save-excursion
  893.       (mapcar (function
  894.            (lambda (buf)
  895.          (set-buffer buf)
  896.          (and (eq mode major-mode)
  897.               (mode-motion+-hook-uninstall buf))))
  898.           (buffer-list)))))
  899.   
  900.  
  901. ;; Setting buffer, mode and default motion handlers
  902.  
  903. (defun set-buffer-motion-handler (buffer handler-name)
  904.   "Make the motion handler named HANDLER-NAME (a symbol) the buffer
  905. motion handler of BUFFER.  If HANDLER-NAME is nil, the corresponding
  906. buffer motion handler is removed.  If HANDLER-NAME isn't the name of a
  907. known motion handler, an error is signaled. When called interactively,
  908. completion is provided for available buffers and motion handlers.
  909.  
  910.     1.\) buffer motion handler
  911.     2.\) mode motion handler
  912.     3.\) default motion handler"
  913.   (interactive (list (read-buffer-name "Set motion handler of buffer: "
  914.                        (buffer-name (current-buffer)))
  915.              (read-motion-handler-name)))
  916.  
  917.   ;; kill old mode motion extent, because the new handler
  918.   ;; might want to initialize it differently
  919.   (if mode-motion-extent 
  920.       (progn 
  921.     (detach-extent mode-motion-extent)
  922.     (setq mode-motion-extent nil)))
  923.   (or buffer (setq buffer (current-buffer)))
  924.   (or (get-buffer buffer)
  925.       (error "No such buffer: %s" buffer))
  926.   (save-excursion 
  927.     (set-buffer buffer)
  928.     (setq buffer-motion-handler
  929.       ;; remove it if `nil'
  930.       (and handler-name
  931.            ;; set the handler if known
  932.            (or (find-motion-handler handler-name)
  933.            ;; error otherwise
  934.            (error "Not a known motion handler: %s"
  935.               handler-name)))))
  936.   (if (interactive-p)
  937.       (if handler-name
  938.       (message "Motion handler for buffer %s is `%s'." 
  939.            (current-buffer) handler-name)
  940.       (message "Motion handler removed for buffer %s." 
  941.            (current-buffer))))
  942.   handler-name)
  943.  
  944. (defun read-buffer-name (prompt &optional initial-input)
  945.   (completing-read prompt
  946.            (mapcar #'(lambda (buf) (list (buffer-name buf)))
  947.                (buffer-list))
  948.            ;; don't take buffers that start with a blank
  949.            #'(lambda (list) (not (eq (aref (car list) 0) ? )))
  950.            t
  951.            initial-input))
  952.  
  953. (defun set-mode-motion-handler (mode handler-name)
  954.   "Make the motion handler named HANDLER-NAME (a symbol) the mode motion
  955. handler for all buffers with major-mode MODE.  If HANDLER-NAME is nil,
  956. the corresponding mode motion handler is removed.  If HANDLER-NAME
  957. isn't the name of a known motion handler, an error is signaled. When
  958. called interactively, completion is provided for available motion
  959. handlers.
  960.  
  961.     1.\) buffer motion handler
  962.     2.\) mode motion handler
  963.     3.\) default motion handler"
  964.   (interactive (list (intern (completing-read "Major mode: "
  965.                           obarray
  966.                           'fboundp    
  967.                           nil 
  968.                           (symbol-name major-mode)))
  969.              (read-motion-handler-name)))
  970.   ;; kill old mode motion extent, because the new handler
  971.   ;; might want to initialize it differently
  972.   (if mode-motion-extent 
  973.       (progn 
  974.     (detach-extent mode-motion-extent)
  975.     (setq mode-motion-extent nil)))
  976.   (put mode 'mode-motion-handler 
  977.     ;; remove it if `nil'
  978.     (and handler-name
  979.          ;; set the handler if known
  980.          (or (find-motion-handler handler-name)
  981.          ;; error otherwise
  982.          (error "Not a known mode motion handler: %s" handler-name))))
  983.   (if (interactive-p)
  984.       (if handler-name
  985.       (message "Motion handler for %s is `%s'." mode handler-name)
  986.       (message "Mode motion handler for %s removed." mode)))
  987.   handler-name)
  988.  
  989. (defun set-default-motion-handler (handler-name)
  990.   "Make the motion handler named HANDLER-NAME (a symbol) the default.
  991.  
  992. If HANDLER-NAME is nil, the current default motion handler is removed.  If
  993. HANDLER-NAME isn't the name of a known motion handler, an error is
  994. signalled. When called interactively, completion is provided for available
  995. motion handlers.
  996.  
  997. The motion handler used in a given buffer is determined by the following
  998. most-specific first list: buffer motion handler, mode motion handler, default
  999. motion handler." 
  1000.   (interactive (list (read-motion-handler-name)))
  1001.   ;; kill old mode motion extent, because the new handler
  1002.   ;; might want to initialize it differently
  1003.   (if mode-motion-extent 
  1004.       (progn 
  1005.     (detach-extent mode-motion-extent)
  1006.     (setq mode-motion-extent nil)))
  1007.   (setq default-motion-handler
  1008.     ;; remove it if `nil'
  1009.     (and handler-name
  1010.          ;; set the handler if known
  1011.          (or (find-motion-handler handler-name)
  1012.          ;; error otherwise
  1013.          (error "Not a known motion handler: %s" handler-name))))
  1014.   (if (interactive-p)
  1015.       (if handler-name
  1016.       (message "Default motion handler is `%s'." handler-name)
  1017.       (message "Default motion handler removed.")))
  1018.   handler-name)
  1019.  
  1020. (defun read-motion-handler-name ()
  1021.   (intern-soft (completing-read "Motion handler: "
  1022.                 (mapcar #'(lambda (entry)
  1023.                         (list (symbol-name (car entry))))
  1024.                     motion-handler-alist)
  1025.                 nil t)))
  1026.  
  1027. ;; clear the last active motion extent when leaving a frame.
  1028. (defun mode-motion-clear-extent (&optional extent)
  1029.   "Clear EXTENT, i.e. make it have no visible effects on the frame.
  1030. EXTENT defaults to the current buffer's mode-motion-extent."
  1031.   (or extent (setq extent mode-motion-extent))
  1032.   (and extent 
  1033.        (extent-live-p extent)
  1034.        (not (extent-detached-p extent))
  1035.        (extent-buffer extent)
  1036.        (buffer-name (extent-buffer extent))
  1037.        (progn 
  1038.      ;; unhighlight it 
  1039.      (highlight-extent extent nil)
  1040.      ;; make it span a region that isn't visible and selectable
  1041.      ;; Can this be done more elegantly? 
  1042.      (detach-extent extent))))
  1043.  
  1044. (defun mode-motion-clear-last-extent (&optional frame)
  1045.   "Clear the mode-motion-last-extent."
  1046.   (or (popup-menu-up-p) (mode-motion-clear-extent mode-motion-last-extent)))
  1047.  
  1048. (defun mode-motion+-highlight (event)
  1049.   "Highlight the thing under the mouse using a mode-specfic motion handler.
  1050. See list-motion-handlers for more details."
  1051.   (mode-motion-clear-last-extent)
  1052.   (and (event-buffer event)
  1053.        (cond ((and mouse-grabbed-buffer
  1054.            ;; first try to do minibuffer specific highlighting
  1055.            (find-motion-handler 'minibuffer)
  1056.            (let ((mode-motion-highlight-lines-when-behind nil))
  1057.              (and (event-point event)
  1058.               (or (extent-at (event-point event)
  1059.                      (event-buffer event) 'highlight)
  1060.                   (mode-motion-highlight-with-handler
  1061.                    (find-motion-handler 'minibuffer) event))))))
  1062.          (t (mode-motion-highlight-with-handler
  1063.          (get-current-motion-handler) event))))
  1064.   ;; Return nil since now this is used as a hook, and we want to let
  1065.   ;; any other hook run after us.
  1066.   nil)
  1067.  
  1068. (defun get-current-motion-handler ()
  1069.   (or (and (boundp 'buffer-motion-handler) buffer-motion-handler)
  1070.       (get major-mode 'mode-motion-handler)
  1071.       default-motion-handler))
  1072.  
  1073. (defun mode-motion-highlight-with-handler (handler event)
  1074.   ;; Perform motion highlighting using HANDLER. Information about the
  1075.   ;; current mouse position is taken form EVENT. 
  1076.   (and handler
  1077.        (let ((point (event-point event))
  1078.          (buffer (event-buffer event))
  1079.          (window (event-window event))
  1080.          (window-config (current-window-configuration))
  1081.          (buffer-save (current-buffer))
  1082.          (point-save (point))
  1083.          region)
  1084.      ;; save-window-excursion and restore buffer
  1085.      (unwind-protect
  1086.          (progn
  1087.            (and buffer
  1088.             (set-buffer buffer)
  1089.             (select-window window))
  1090.        
  1091.            ;; kludge: if point = end-of-window, then probably the mouse
  1092.            ;; is actually between the last line and the modeline.  In
  1093.            ;; this case move point to back one
  1094.            (and point
  1095.             (not (< point (window-end window)))
  1096.             (setq point (1- point)))
  1097.            ;; Create a new mode-motion-extent if there isn't one 
  1098.            ;; (or a destroyed one)
  1099.            (if (and (extent-live-p mode-motion-extent)
  1100.             (extent-buffer mode-motion-extent))
  1101.            ()
  1102.          (setq mode-motion-extent (make-extent nil nil buffer))
  1103.          (set-extent-priority mode-motion-extent 1))
  1104.            (if (and 
  1105.             ;; compute the region to be highlighted
  1106.             (setq region
  1107.               (if point
  1108.                   ;; compute the mode-motion region using the 
  1109.                   ;; handlers boundary function
  1110.                   (condition-case nil;; c
  1111.                   (funcall
  1112.                    (motion-handler-boundary-function handler)
  1113.                    point)
  1114.                 ;; Messages that appear during computing the
  1115.                 ;; region may be displayed not done
  1116.                 ;; here because it's rather disturbing
  1117.                 (error
  1118.                  ;; (setq message (format "%s" (car (cdr c))))
  1119.                  nil))
  1120.                 ;; otherwise highlight the whole line mouse is
  1121.                 ;; behind but only if the line isn't empty
  1122.                 (if mode-motion-highlight-lines-when-behind
  1123.                 (unwind-protect
  1124.                     (progn 
  1125.                       ;; (message "%s" (event-window event))
  1126.                       (move-to-window-line
  1127.                        (if (< emacs-minor-version 12)
  1128.                        (- (event-y event) 
  1129.                           (nth 1 (window-edges window)))
  1130.                      (event-y event)))
  1131.                       (beginning-of-line)
  1132.                       (if (= (following-char) ?\n)
  1133.                       ;; empty line 
  1134.                       ()
  1135.                     (thing-region
  1136.                      (point)
  1137.                      (progn 
  1138.                        (end-of-line)
  1139.                        ;; for `follow-point' behavoir
  1140.                        (setq point (point))
  1141.                        ;; fetch also the newline, if any
  1142.                        ;; -- handy for copying >1 line
  1143.                        (if (eobp) point (1+ point))))))
  1144.                   (goto-char point-save)))))
  1145.             ;; (message "region: %s" region)
  1146.             ;; the region might be in reverse order. Stop in this case
  1147.             (<= (car region) (cdr region)))
  1148.            (progn 
  1149.              ;; set the extent face
  1150.              (set-extent-face
  1151.               mode-motion-extent (motion-handler-face handler))
  1152.              ;; set the new boundary
  1153.              (set-extent-endpoints 
  1154.               mode-motion-extent (car region) (cdr region))
  1155.              ;; highlight if required
  1156.              (set-extent-property mode-motion-extent 'highlight
  1157.                       (motion-handler-highlight handler))
  1158.              (highlight-extent mode-motion-extent
  1159.                        (motion-handler-highlight handler))
  1160.              ;; make point follow the mouse or point to the beginning
  1161.              ;; of the line do not move the cursor if a mark is set
  1162.              (cond ((and (motion-handler-follow-point handler)
  1163.                  (not (mark)))
  1164.                 (goto-char point)
  1165.                 ;; kludge to keep the cursor out the way
  1166.                 (if (or (eq (motion-handler-boundary-function
  1167.                      handler)
  1168.                     'line-boundaries)
  1169.                     (eq (motion-handler-boundary-function
  1170.                      handler)
  1171.                     'visible-line-boundaries))
  1172.                 (beginning-of-line))))
  1173.              (if (and mode-motion-focus-on-window
  1174.                   (or (eq mode-motion-focus-on-window t)
  1175.                   (motion-handler-follow-point handler)))
  1176.              ;; Select the current window FROM OUTSIDE the
  1177.              ;; `save-window-excursion' that surrounds the call
  1178.              ;; to the current function. This also avoids
  1179.              ;; conflicts with running process filters.
  1180.              (enqueue-eval-event 'select-window (selected-window)))
  1181.              ;; snap in effect, but it ain't yet workin'
  1182.              ;; (message "X: %sl; Y: %s"(event-x event)(event-y event))
  1183.              ;; (and motion-handler-snap-in
  1184.              ;;    (set-mouse-position
  1185.              ;;    (window-frame (event-window event))
  1186.              ;;    (event-x event)
  1187.              ;;    (event-y event)))
  1188.              (setq mode-motion-last-extent mode-motion-extent)
  1189.              ;; signal success
  1190.              t)
  1191.          ;; signal failiure
  1192.          nil))
  1193.        (set-window-configuration window-config)
  1194.        (set-buffer buffer-save)))))
  1195.  
  1196. ;; Motion Event debugging
  1197. ;;
  1198. ;; Useful to see what information is available from motion events
  1199.  
  1200. (defun debug-motion-handler (event)
  1201.    (let* ((window (event-window event))
  1202.       (frame (or (event-frame event) (selected-frame)))
  1203.       (buffer (and window (event-buffer event)))
  1204.       (point  (and buffer (event-point event))))
  1205.      (with-output-to-temp-buffer "*Debug Motion Handler Output*"
  1206.        (princ 
  1207.     (format "\
  1208.  Window: %s
  1209.  Frame: %s
  1210.  Buffer: %s
  1211.  (event-x, event-y): (%s, %s)
  1212.  (event-x-pixel, event-y-pixel): (%s, %s)
  1213.  Point: %s
  1214.  Timestamp: %s"
  1215.     window 
  1216.         frame 
  1217.         buffer 
  1218.         (event-x event) (event-y event) 
  1219.         (event-x-pixel event) (event-y-pixel event)
  1220.         point 
  1221.         (event-timestamp event))))))
  1222.  
  1223. ;(let ((mouse-motion-handler 'debug-motion-handler)
  1224. ;      (temp-buffer-show-function nil))
  1225. ;  (read-char))
  1226.  
  1227. ;; Set of copy/kill/move functions for usage with highlighted regions
  1228.  
  1229. (put 'mode-motion-move 'pending-delete t)
  1230. (put 'mode-motion-copy 'pending-delete t)
  1231.  
  1232. (defun mode-motion-move ()
  1233.   "Move the motion active region to point." 
  1234.   (interactive)
  1235.   (mode-motion-insert-text (mode-motion-copy/delete t)))
  1236.  
  1237. (defun mode-motion-kill ()
  1238.   "Kill the motion active region and push it onto the kill ring."
  1239.   (interactive)
  1240.   (mode-motion-copy/delete t t t))
  1241.  
  1242. (defun mode-motion-copy ()
  1243.   "Copy the motion active region to point."
  1244.   (interactive)
  1245.   (mode-motion-insert-text (mode-motion-copy/delete)))
  1246.  
  1247. (defun mode-motion-copy-as-kill ()
  1248.   "Delete the motion active region and push it onto the kill ring.
  1249. Set point to the place where deletion happened."
  1250.   (interactive)
  1251.   (mode-motion-copy/delete nil t)
  1252.   (message "Text copied to the to ring and cut buffer."))
  1253.  
  1254. (defun mode-motion-copy/delete (&optional delete copy-as-kill set-point)
  1255.   "Return the string that is designated by the current motion active region. 
  1256. Arguments are:
  1257.            EVENT - a mouse click event used to identify the buffer and window 
  1258. &optional DELETE - delete the motion active text region
  1259.     COPY-AS-KILL - copy the string to the kill ring
  1260.        SET-POINT - set point to the start of the motion active region."
  1261.   (let ((old-buf (current-buffer))
  1262.     (old-window (selected-window)))
  1263.     (unwind-protect 
  1264.     (let ((extent (or primary-selection-extent
  1265.               (and (extentp mode-motion-last-extent)
  1266.                    (not (extent-property mode-motion-last-extent
  1267.                              'detached))
  1268.                    mode-motion-last-extent))))
  1269.  
  1270.       (if (and (extentp extent)
  1271.            (set-buffer (extent-buffer extent))
  1272.            (not 
  1273.             ;; zero length extents
  1274.             (= (extent-start-position extent)
  1275.                (extent-end-position extent))))
  1276.  
  1277.           (let* ((start (extent-start-position extent))
  1278.              (end (extent-end-position extent))
  1279.              (text 
  1280.               (buffer-substring
  1281.                (extent-start-position extent)
  1282.                (extent-end-position extent))))
  1283.  
  1284.         (cond (copy-as-kill
  1285.                (copy-region-as-kill start end)
  1286.                (if (or (not kill-hooks)
  1287.                 (eq kill-hooks 'ignore))
  1288.                (progn 
  1289.                  (x-own-selection-internal 'PRIMARY text)
  1290.                  (x-own-clipboard text)))))
  1291.  
  1292.         (cond (delete 
  1293.                (kill-region start end)
  1294.                (x-own-selection-internal 'PRIMARY text)
  1295.                ;; (select-window window)
  1296.                (if set-point 
  1297.                (goto-char start))))
  1298.  
  1299.         (setq this-command 'mode-motion+)
  1300.         text)
  1301.         (error "No current primary or motion selection.")
  1302.         ))
  1303.       (set-buffer old-buf)
  1304.       (select-window old-window))))
  1305.  
  1306. (defun mode-motion-insert-text (text)
  1307.   "Insert TEXT at point. Also insert one space if the 
  1308. preceeding character is a word constituent or a closing paren."
  1309.   (or text (error "No highlighted text to copy."))
  1310.   (let ((prec-char-syntax (char-syntax (preceding-char))))
  1311.     (if (memq  prec-char-syntax '(?w ?\))) (insert " "))
  1312.     (insert text)))
  1313.  
  1314. ;; Boundary functions
  1315. ;;
  1316. ;; The following  functions are already provided by the thing package:
  1317. ;; thing-boundaries
  1318. ;; thing-symbol
  1319. ;; thing-word
  1320.  
  1321. (defun char-boundaries (point) (thing-region point (1+ point)))
  1322.       
  1323. (defun visible-line-boundaries (point)
  1324.   (save-excursion
  1325.     (goto-char point)
  1326.     (beginning-of-line)
  1327.     (skip-chars-forward " \t")
  1328.     (if (and (eq major-mode 'dired-mode)
  1329.          (save-excursion (dired-move-to-filename)))
  1330.     (let ((start (point)))
  1331.       (end-of-line)
  1332.       (skip-chars-backward " \t")
  1333.       (thing-region start (point))))))
  1334.  
  1335. (defun line-boundaries (point)
  1336.   (save-excursion
  1337.     (goto-char point)
  1338.     (beginning-of-line)
  1339.     (if (and (eq major-mode 'dired-mode)
  1340.          (save-excursion (dired-move-to-filename)))
  1341.     (let ((start (point)))
  1342.       (end-of-line)
  1343.       (thing-region start (point))))))
  1344.  
  1345. (defun cvs-line-boundaries (point)
  1346.     (save-excursion
  1347.       (goto-char point)
  1348.       (beginning-of-line)
  1349.       (if (looking-at "^[* ] ")
  1350.       (thing-region  (point) (progn (end-of-line) (point))))))
  1351.       
  1352. (defun latex-boundaries (here)
  1353.   (setq *last-thing* 'sexp)
  1354.   (tex-boundaries 
  1355.    here ?\\ "a-zA-Z"
  1356.    ;; begin-fwd-regexp
  1357.    "\\\\begin *{ *\\([a-z]*\\) *}"
  1358.    ;; end-fwd-regexp
  1359.    "\\(\\\\end *{ *%s *}\\)\\|\\(\\\\begin *{ *%s *}\\)"
  1360.    ;; begin-bwd-regexp
  1361.    "\\\\end *{ *\\([a-z]*\\) *}"
  1362.    ;; begin-bwd-regexp
  1363.    "\\(\\\\end *{ *%s *}\\)\\|\\(\\\\begin *{ *%s *}\\)"
  1364.    ;; param-cmd-regexp
  1365.    "\\\\[a-zA-Z]+[ \n\t]*{"))
  1366.  
  1367. (defvar texinfo-paired-commands 
  1368.   (mapconcat 
  1369.    'identity 
  1370.    '(
  1371.      "enumerate"
  1372.      "example"
  1373.      "group"
  1374.      "ifinfo" 
  1375.      "iftex" 
  1376.      "ignore" 
  1377.      "itemize"
  1378.      "menu"
  1379.      "quotation"
  1380.      "table"
  1381.      "tex"
  1382.      "titlepage"
  1383.      ) 
  1384.    "\\|"))
  1385.  
  1386. (defvar texinfo-begin-fwd-regexp 
  1387.   (format "@\\(%s\\)" texinfo-paired-commands))
  1388. (defvar texinfo-end-bwd-regexp
  1389.   (format "@end *\\(%s\\)" texinfo-paired-commands))
  1390.  
  1391. (defun texinfo-boundaries (here)
  1392.   (tex-boundaries 
  1393.    here ?@ "a-z"
  1394.    texinfo-begin-fwd-regexp
  1395.    ;; end-fwd-regexp
  1396.    "\\(@end *%s\\)\\|\\(@%s\\)"
  1397.    ;; end-bwd-regexp
  1398.    texinfo-end-bwd-regexp
  1399.    ;; begin-bwd-regexp
  1400.    "\\(@end *%s\\)\\|\\(@%s\\)"
  1401.    ;; param-cmd-regexp
  1402.    "@\\(TeX\\|[a-zA]+\\)[ \n\t]*{"))
  1403.  
  1404. (defun tex-boundaries 
  1405.   (here cmd-start-character cmd-word-character
  1406.     begin-fwd-regexp end-fwd-regexp
  1407.     end-bwd-regexp begin-bwd-regexp
  1408.     param-cmd-regexp)
  1409.   "Generic TeX dialect scanner.
  1410. Parameters: 
  1411. cmd-start-character: character that starts a command 
  1412.     (`\' in (La)TeX, `@' in Texinfo)
  1413. cmd-word-character:  regexpression to be used by the function
  1414.     `skip-chars-backward' allowing to skip over command 
  1415.     characters other than `cmd-start-character'
  1416. begin-fwd-regexp: regexpression matching the begin part of a 
  1417.     text stretch, used in forward search. 
  1418. end-fwd-regexp: regexpression matching the end part of a 
  1419.     text stretch, used in forward search
  1420. end-bwd-regexp: regexpression matching the end part of a 
  1421.     text stretch, used in backward search.
  1422. begin-bwd-regexp: regexpression matching the begin part of a 
  1423.     text stretch, used in backward search.
  1424. param-cmd-regexp: regexpression matching a parameterized command 
  1425.         \(including the open parenthesis\)"
  1426.   (save-excursion
  1427.     (goto-char here)
  1428.     (cond ((= (following-char) cmd-start-character)
  1429.        (forward-char 1))
  1430.       ((= (char-syntax (following-char)) ?w)
  1431.        (skip-chars-backward cmd-word-character)))
  1432.     (if (/= (preceding-char) cmd-start-character)
  1433.     (thing-boundaries here)
  1434.       (forward-char -1)
  1435.       (catch 'return 
  1436.     (cond ((looking-at begin-fwd-regexp)
  1437.            (let* ((start (point))
  1438.               (env (buffer-substring 
  1439.                 (match-beginning 1) (match-end 1)))
  1440.               (regexp (format end-fwd-regexp env env))
  1441.               (count 0))
  1442.          (while (re-search-forward regexp nil t)
  1443.            (cond ((match-beginning 2) ; \begin
  1444.               (setq count (1+ count)))
  1445.              ((match-beginning 1) ; \end
  1446.               (setq count (1- count))
  1447.               (if (= count 0) 
  1448.                   (throw 'return 
  1449.                      (thing-region start (point)))))))))
  1450.           ((looking-at end-bwd-regexp)
  1451.            (let* ((end (match-end 0))
  1452.               (env (buffer-substring 
  1453.                 (match-beginning 1) (match-end 1)))
  1454.               (regexp 
  1455.                (format begin-bwd-regexp env env))
  1456.               (count 1))
  1457.          (while (re-search-backward regexp nil t)
  1458.            (cond ((match-beginning 1) ; \end
  1459.               (setq count (1+ count)))
  1460.              ((match-beginning 2) ; \begin
  1461.               (setq count (1- count))
  1462.               (if (= count 0) 
  1463.                   (throw 'return (thing-region (point) end))))
  1464.              ))))
  1465.           ;; tex macros of the form \cmd {...}
  1466.           ((looking-at param-cmd-regexp)
  1467.            (thing-region 
  1468.         (point)
  1469.         (progn 
  1470.           (goto-char (1- (match-end 0)))
  1471.           (forward-sexp 1)
  1472.           (point))))
  1473.           ;; fetch the current macro (with backslash)
  1474.           (t (thing-region (point) (progn (forward-word 1) (point)))))))))
  1475.  
  1476. ;; special parse of buffer for valid selectable info
  1477. (defun minibuffer-selection-boundaries (point)
  1478.   (let ((old-syntax (syntax-table)))
  1479.     (unwind-protect
  1480.     (progn 
  1481.       ;; best syntax table for recognizing symbols
  1482.       (set-syntax-table emacs-lisp-mode-syntax-table)
  1483.       (let ((file-completion (eq minibuffer-completion-table
  1484.                      'read-file-name-internal))
  1485.         region
  1486.         minibuf-string        ;contents of minibuffer
  1487.         buffer-string        ;string to be highlighted (or not)
  1488.         prefix            ;prefix calculated from minibuf-string
  1489.         string            ;string to be verified in the
  1490.                     ;completion table 
  1491.         )
  1492.         (and
  1493.  
  1494.          (setq region (if file-completion
  1495.                   (thing-filename point)
  1496.                 (thing-symbol point)))
  1497.  
  1498.          (setq
  1499.           minibuf-string        ; contents of minibuffer
  1500.           (save-excursion
  1501.         (set-buffer mouse-grabbed-buffer)
  1502.         (buffer-string))
  1503.  
  1504.           buffer-string        ; string to be highlighted (or not)
  1505.           (buffer-substring (car region) (cdr region))
  1506.                
  1507.           prefix
  1508.           (if file-completion
  1509.           (file-name-nondirectory minibuf-string)
  1510.         minibuf-string)
  1511.  
  1512.           string
  1513.           (if file-completion
  1514.           (concat (file-name-directory minibuf-string) buffer-string)
  1515.         buffer-string))
  1516.          
  1517.          (if (or (and (fboundp 'ange-ftp-ftp-path)
  1518.               (or (ange-ftp-ftp-path buffer-string)
  1519.                   (ange-ftp-ftp-path string)))
  1520.              (and (fboundp 'efs-ftp-path)
  1521.               (or (efs-ftp-path buffer-string)
  1522.                   (efs-ftp-path string))))
  1523.          ;; #### Like our counterpart in mode-motion: evil evil evil
  1524.          t
  1525.            (if file-completion
  1526.            (try-completion string
  1527.                    minibuffer-completion-table
  1528.                    minibuffer-completion-predicate)
  1529.          (eq 't (try-completion string
  1530.                     minibuffer-completion-table
  1531.                     minibuffer-completion-predicate))))
  1532.  
  1533.          ;; the result is the region to be highlighted
  1534.          region)))
  1535.       (set-syntax-table old-syntax))))
  1536.  
  1537. ;; C source code scanner 
  1538. (defvar c-statement-starting-keyword-regexpr
  1539.   "\\(if\\|for\\|while\\|do\\|switch\\|break\\|continue\\)\\b")
  1540.  
  1541. (defun c-boundaries (here)
  1542.   (setq *last-thing* 'sexp)
  1543.   (save-excursion
  1544.     (goto-char here)
  1545.     (let ((following-char (following-char))
  1546.       (preceding-char (preceding-char))
  1547.       aux)
  1548.       (if (= (char-syntax following-char) ?w)
  1549.       (progn 
  1550.         (skip-chars-backward "a-zA-Z")
  1551.         (setq aux (point))
  1552.         (skip-chars-backward "\n\t ")
  1553.         (if (= (preceding-char) ?#)
  1554.         (forward-char -1)
  1555.           (goto-char aux))))
  1556.       (if (and (= following-char ?*)
  1557.            (= preceding-char ?/))
  1558.       (forward-char -1))
  1559.       (if (and (= following-char ?/)
  1560.            (= preceding-char ?*))
  1561.       (forward-char -1))
  1562.       (cond
  1563.        ((= (following-char) ?#) (c-scan-preproc-macros))
  1564.        ((looking-at "/\\*")    ; begin comment
  1565.     (let ((start (match-beginning 0)))
  1566.       (if (search-forward "*/" nil t)
  1567.           (thing-region start (match-end 0)))))
  1568.        ((looking-at "\\*/")    ; end comment
  1569.     (let ((end (match-end 0)))
  1570.       (if (search-backward "/*" nil t)
  1571.           (thing-region (match-beginning 0) end))))
  1572.        ((looking-at c-statement-starting-keyword-regexpr) ; if for while do etc
  1573.     (thing-region (match-beginning 0)
  1574.               (c-forward-statement 
  1575.                (buffer-substring (match-beginning 1) (match-end 1)))))
  1576.        ((looking-at "else\\b")
  1577.     (thing-region (match-beginning 0) (c-forward-else)))
  1578.        (t (if (= (char-syntax (following-char)) ?.)
  1579.           (thing-region here  (1+ here))
  1580.         (thing-boundaries here)))))))
  1581.  
  1582.  
  1583. (defun c-scan-preproc-macros ()
  1584.   (cond 
  1585.    ((looking-at "^#[ \n\t]*include[ \n\t]*[<\"][^>\"]*[>\"]")   ; #include
  1586.     (thing-region (match-beginning 0) (match-end 0)))
  1587.    ((looking-at "^#[ \n\t]*\\(define\\|undef\\)") ; #define, #undef
  1588.     (thing-region
  1589.      (match-beginning 0) 
  1590.      (progn 
  1591.        (end-of-line)
  1592.        (while (= (preceding-char) ?\\)
  1593.      (forward-line 1)
  1594.      (end-of-line))
  1595.        (point))))
  1596.    ;; #if, #ifdef, #ifndef, #else, #elif
  1597.    ((looking-at "^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|else\\|elif\\)\\b")
  1598.     (let ((start (match-beginning 0))
  1599.       (counter 1)
  1600.       match)
  1601.       (goto-char (match-end 0))
  1602.       (while (and (>= counter 1)
  1603.           (re-search-forward 
  1604.            "^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|endif\\)\\b"
  1605.            nil t))
  1606.     (setq match 
  1607.           (buffer-substring (match-beginning 1) (match-end 1)))
  1608.     (setq counter 
  1609.           (if (string= match "endif")
  1610.           (1- counter)
  1611.         (1+ counter))))
  1612.       (if (= counter 0)
  1613.       (thing-region start (match-end 0)))))
  1614.    ((looking-at "^#[ \n\t]*endif\\b")   ; #endif
  1615.     (let ((end (match-end 0))
  1616.       (counter 1)
  1617.       match)
  1618.       (goto-char (match-beginning 0))
  1619.       (while (and (>= counter 1)
  1620.           (re-search-backward
  1621.            "^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|endif\\)\\b"
  1622.            nil t))
  1623.     (setq match 
  1624.           (buffer-substring (match-beginning 1) (match-end 1)))
  1625.     (setq counter 
  1626.           (if (string= match "endif")
  1627.           (1+ counter)
  1628.         (1- counter))))
  1629.       (if (= counter 0)
  1630.       (thing-region (match-beginning 0) end))))))
  1631.  
  1632. (defun c-skip-over-comment ()
  1633.   (let ((aux (point)))
  1634.     (skip-chars-forward "\n\t ")
  1635.     (or (and (= (following-char) ?/)
  1636.          (= (char-after (1+ (point))) ?*)
  1637.          (search-forward "*/" nil t)
  1638.          (point))
  1639.     (goto-char aux))))
  1640.  
  1641. (defun c-forward-statement (&optional keyword)
  1642.   (c-skip-over-comment)
  1643.   (skip-chars-forward " \n\t")
  1644.   (or keyword (setq keyword 
  1645.             (if (looking-at c-statement-starting-keyword-regexpr)
  1646.             (buffer-substring 
  1647.              (match-beginning 1)
  1648.              (match-end 1)))))
  1649.   (if keyword
  1650.       (cond ((string= keyword "if")
  1651.          (c-forward-if))
  1652.         ((string= keyword "do")
  1653.          (c-forward-do-while))
  1654.         ((member keyword '("for" "while" "switch"))
  1655.          (c-forward-for/while/switch))
  1656.         ((member keyword '("break" "continue"))
  1657.          (c-forward-break/continue)))
  1658.     (cond ((= (following-char) ?\{)
  1659.        (forward-list 1)
  1660.        (point))
  1661.       (t
  1662.        ;; Here I use that each C statement other then 
  1663.        ;; a bloc, if, while, for, do ... ends in a `;'
  1664.        (let (char)
  1665.          (catch 'exit
  1666.            (while t
  1667.          (if (eobp) (throw 'exit nil))
  1668.          (setq char (following-char))
  1669.          (cond ((= (char-syntax char) ?.) 
  1670.             (forward-char 1)
  1671.             (if (= char ?\;) (throw 'exit (point))))
  1672.                (t (forward-sexp 1)
  1673.               (skip-chars-forward " \n\t"))))))))))
  1674.  
  1675. (defun c-forward-if ()
  1676.   (let (aux)
  1677.     (forward-word 1) ; if
  1678.     (forward-list 1) 
  1679.     (c-forward-statement)
  1680.     (setq aux (point))
  1681.     (skip-chars-forward "\n\t ")
  1682.     (if (looking-at "else\\b")
  1683.     (c-forward-else)
  1684.     (goto-char aux))))
  1685.  
  1686. (defun c-forward-else ()
  1687.   (forward-word 1) ; else
  1688.   (c-forward-statement))
  1689.  
  1690. (defun c-forward-for/while/switch ()
  1691.   (forward-word 1) ; for
  1692.   (forward-list 1)
  1693.   (c-forward-statement))
  1694.  
  1695. (defun c-forward-do-while ()
  1696.   (forward-word 1) ; do ... while
  1697.   (c-forward-statement)
  1698.   (c-forward-for/while/switch))
  1699.  
  1700. (defun c-forward-switch ()
  1701.   (forward-word 1) ; switch
  1702.   (forward-list 2)
  1703.   (point))
  1704.  
  1705. (defun c-forward-break/continue ()
  1706.   (forward-word 1) ; keyword
  1707.   (c-skip-over-comment)
  1708.   (skip-chars-forward "\n\t ")
  1709.   (if (= (following-char) ?\;)
  1710.       (goto-char (1+ (point)))))
  1711.  
  1712. ;; Tcl syntax scanner
  1713. (defvar tcl-builtin-commands nil
  1714.   "Alist of information about tcl syntax for the tcl-boundaries function.  
  1715. An entry has the form 
  1716.     \(<command-string> . <syntax description>\) 
  1717. where 
  1718.     <command-string>     is the name of a tcl command
  1719.     <syntax description> is one of 
  1720.             list of integers: the number of possible arguments
  1721.         t:              any number of arguments")
  1722.  
  1723. (defconst tcl-commands
  1724.   '(
  1725.     ("append"    . (2 . nil))
  1726.     ("array"    . (2 . 3))
  1727.     ("break"    . 0)
  1728.     ("case"     . 3)
  1729.     ("catch"    . 1)
  1730.     ("cd"    . 1)
  1731.     ("close"    . 1)
  1732.     ("concat"    . t)
  1733.     ("continue"    . 0)
  1734.     ("else"     . (1 . nil))
  1735.     ("elseif"    . (1 . nil))
  1736.     ("eof"    . 1)
  1737.     ("error"    . t)
  1738.     ("eval"     . t)
  1739.     ("exec"     . t)
  1740.     ("exit"    . (0 . 1))
  1741.     ("expr"     . 1)
  1742.     ("file"    . (2 . nil))
  1743.     ("flush"    . 1)
  1744.     ("for"     . 4)
  1745.     ("foreach"     . 3)
  1746.     ("format"    . (1 . nil))
  1747.     ("gets"    . (1 . 2))
  1748.     ("glob"    . t)
  1749.     ("global"     . (1 . nil))
  1750.     ("history"    . t)
  1751.     ("if"     . (2 . nil))
  1752.     ("incr"     . (1 . 2))
  1753.     ("info"    . (1 . 4))
  1754.     ("join"    . (1 . 2))
  1755.     ("lappend"    . (2 . nil))
  1756.     ("lindex"     . 2)
  1757.     ("linsert"    . (3 . nil))
  1758.     ("list"    . t)
  1759.     ("llength"     . 1)
  1760.     ("lrange"     . 3)
  1761.     ("lreplace"    . (3 . nil))
  1762.     ("lsearch"     . 2)
  1763.     ("lsort"    . 1)
  1764.     ("open"    . (1 . 2))
  1765.     ("proc"     . 3)
  1766.     ("puts"    . (1 . 3))
  1767.     ("pwd"    . 0)
  1768.     ("read"    . (1 . 2))
  1769.     ("regexp"    . (2 . nil))
  1770.     ("regsub"    . (4 . 6))
  1771.     ("rename"    . 2)
  1772.     ("return"    . (0 .1))
  1773.     ("scan"    . (3 . nil))
  1774.     ("seek"    . (2 . 3))
  1775.     ("set"     . (1 . 2))
  1776.     ("source"    . 1)
  1777.     ("split"    . (1 . 2))
  1778.     ("string"    . (2 . 4))
  1779.     ("tell"    . 1)
  1780.     ("time"    . (1 .2))
  1781.     ("trace"    . (1 . nil))
  1782.     ("unknown"    . (1 . nil))
  1783.     ("unset"    . (1 . nil))
  1784.     ("uplevel"    . (1 . nil))
  1785.     ("upvar"    . (2 . nil))
  1786.     ("while"     . 2)
  1787.     ))
  1788.  
  1789. (defconst tk-commands
  1790.   '(("bind"    . 3)
  1791.     ("button"    . t)
  1792.     ("canvas"    . t)
  1793.     ("frame"    . t)
  1794.     ("label"    . t)
  1795.     ("listbox"    . t)
  1796.     ("menu"    . t)
  1797.     ("menubutton"    . t)
  1798.     ("pack"    . t)
  1799.     ("scrollbar"    . t)
  1800.     ("tree"    . t)
  1801.     ("wm"        . t)
  1802.     ))
  1803.  
  1804. (defconst tcl-tk-commands
  1805.   (nconc tcl-commands tk-commands))
  1806.   
  1807. (defconst tcl-tk-commands-regexp
  1808.   (format "\\(%s\\\)\\W" (mapconcat 'car tcl-tk-commands "\\|")))
  1809.  
  1810. (defun tcl-boundaries (here)
  1811.   (save-excursion
  1812.     (goto-char here)
  1813.     (skip-chars-backward "a-z")
  1814.     (if (looking-at 
  1815.      tcl-tk-commands-regexp)
  1816.     (let* ((count 0) 
  1817.           (start (point))
  1818.           (keyword (buffer-substring
  1819.             (match-beginning 1)
  1820.             (match-end 1)))
  1821.           (syntax-description 
  1822.            (cdr (assoc keyword tcl-tk-commands))))
  1823.       (goto-char (match-end 0))
  1824.       (while (not (looking-at "[ \t]*[]\n;}]"))
  1825.         (setq count (1+ count))
  1826.         (tcl-forward-sexp1)
  1827.         ;; skipping over the parentheses of array expressions:
  1828.         (while (not (or (looking-at "[ \t]*[]\n;}]")
  1829.                 (= (char-syntax (following-char)) ? )))
  1830.           (tcl-forward-sexp1)))
  1831.  
  1832.       (if (cond ((eq syntax-description t))
  1833.             ((integerp syntax-description) 
  1834.              (= syntax-description count))
  1835.             ((consp syntax-description)
  1836.              (and (<= (car syntax-description) count)
  1837.               (or (null (cdr syntax-description))
  1838.                   (<= count (cdr syntax-description))))))
  1839.           (progn 
  1840.         (message "`%s' matched."  keyword)
  1841.         (thing-region start (point)))
  1842.         (progn 
  1843.           (message "wrong syntax: `%s'."  keyword)
  1844.           nil)))
  1845.       (message "")
  1846.       (thing-boundaries here))))
  1847.  
  1848. (defun tcl-forward-sexp (&optional arg)
  1849.   "Move forward across one balanced tcl expression.
  1850. With argument, do it that many times."
  1851.   (interactive "p")
  1852.   (if (< arg 0) (error "negative argument not allowed"))
  1853.   (or arg (setq arg 1))
  1854.   (while (> arg 0)
  1855.     (tcl-forward-sexp1)
  1856.     (setq arg (1- arg))))
  1857.  
  1858. (defun tcl-forward-sexp1 ()
  1859.   (interactive "")  
  1860.   (let ((start (point))
  1861.     next-char syntax (first-scan t))
  1862.     (setq next-char (following-char)
  1863.       syntax (char-syntax next-char))
  1864.  
  1865.     (while (or (= next-char ?\;)
  1866.            (memq syntax '(? ?>)))
  1867.       (forward-char 1)
  1868.       (setq next-char (following-char)
  1869.         syntax (char-syntax next-char)))
  1870.  
  1871.     (condition-case var
  1872.     (catch 'exit 
  1873.       (while t
  1874.         (setq next-char (following-char)
  1875.           syntax (char-syntax next-char))
  1876.         (cond ((= next-char ?\;)
  1877.            (throw 'exit nil))
  1878.           ((memq syntax (if first-scan '(? ?>) '(? ?> ?\))))
  1879.            (throw 'exit nil))
  1880.           (t 
  1881.            (goto-char (or (scan-sexps (point) 1) 
  1882.                   (point-max)))))
  1883.         (setq first-scan nil)))
  1884.       (error (goto-char start)
  1885.          (error (car (cdr var)))))))
  1886.  
  1887. ;; (define-key tcl-mode-map "\M-\C-f" 'tcl-forward-sexp)
  1888.  
  1889. (defun mode-motion-eval-func (eval-func)
  1890.   (let ((old-buf (current-buffer))
  1891.     (old-window (selected-window)))
  1892.     (unwind-protect 
  1893.     (let ((extent (or primary-selection-extent
  1894.               (and (extentp mode-motion-last-extent)
  1895.                    (not (extent-property mode-motion-last-extent
  1896.                              'detached))
  1897.                    mode-motion-last-extent))))
  1898.  
  1899.       (if (and (extentp extent)
  1900.            (set-buffer (extent-buffer extent))
  1901.            (not 
  1902.             ;; zero length extents
  1903.             (= (extent-start-position extent)
  1904.                (extent-end-position extent))))
  1905.  
  1906.           (let* ((start (extent-start-position extent))
  1907.              (end (extent-end-position extent)))
  1908.  
  1909.         (funcall eval-func start end))
  1910.  
  1911.         (error "No current primary or motion selection.")
  1912.         ))
  1913.       (set-buffer old-buf)
  1914.       (select-window old-window))))
  1915.  
  1916. (defun mode-motion-eval-region ()
  1917.   (interactive)
  1918.   (mode-motion-eval-func 'eval-region))
  1919.  
  1920.  
  1921. ;; Motion highlight faces and initialization.
  1922.  
  1923. (defun sect-handler (string)
  1924.   "Return the symbol corresponding to the foo-STRING handler for this sect."
  1925.   (intern-soft (concat (symbol-name mode-motion+-religion) string)))
  1926.  
  1927. (defun mode-motion-init-handlers-according-to-religion (&optional forcep)
  1928.   (interactive)
  1929.   ;; Initialise default motion handlers depending on religious sect!
  1930.   (let ((foo-thing (sect-handler "-thing"))
  1931.     (foo-c (sect-handler "-c"))
  1932.     (foo-LaTeX (sect-handler "-laTeX"))
  1933.     (foo-line@ (sect-handler "-line@"))
  1934.     (foo-vline@ (sect-handler "-vline@")))
  1935.     (if forcep
  1936.     (progn
  1937.       (setq default-motion-handler (find-motion-handler foo-thing))
  1938.       (set-mode-motion-handler 'emacs-lisp-mode foo-thing)
  1939.       (set-mode-motion-handler 'lisp-interaction-mode foo-thing)
  1940.       (set-mode-motion-handler 'c-mode foo-c)
  1941.       (set-mode-motion-handler 'c++-mode foo-c)
  1942.       (set-mode-motion-handler 'c++-c-mode foo-c)
  1943.       (set-mode-motion-handler 'tex-mode foo-LaTeX)
  1944.       (set-mode-motion-handler 'latex-mode foo-LaTeX)
  1945.       (set-mode-motion-handler 'Buffer-menu-mode foo-vline@)
  1946.       (set-mode-motion-handler 'Electric-Buffer-menu-mode foo-vline@)
  1947.       (set-mode-motion-handler 'gnus-Group-mode foo-vline@)
  1948.       (set-mode-motion-handler 'gnus-Subject-mode foo-vline@)
  1949.       (set-mode-motion-handler 'gnus-group-mode foo-vline@)
  1950.       (set-mode-motion-handler 'gnus-subject-mode foo-vline@)
  1951.       (set-mode-motion-handler 'gnus-summary-mode foo-vline@)
  1952.       (set-mode-motion-handler 'dired-mode foo-line@)
  1953.       (set-mode-motion-handler 'compilation-mode foo-line@)
  1954.       (set-mode-motion-handler 'occur-mode foo-line@)
  1955.       (set-mode-motion-handler 'tar-mode foo-vline@)
  1956.       (set-mode-motion-handler 'rmail-summary-mode foo-vline@)
  1957.       (set-mode-motion-handler 'vm-summary-mode (sect-handler "-line"))
  1958.       (set-mode-motion-handler 'tcl-mode (sect-handler "-tcl"))
  1959.       (set-mode-motion-handler 'texinfo-mode (sect-handler "-TeXinfo"))
  1960.       (set-mode-motion-handler 'cvs-mode (sect-handler "-cvs-line")))
  1961.       (setq default-motion-handler
  1962.         (or default-motion-handler (find-motion-handler foo-thing)))
  1963.       (or (get 'emacs-lisp-mode 'mode-motion-handler)
  1964.       (set-mode-motion-handler 'emacs-lisp-mode foo-thing))
  1965.       (or (get 'lisp-interaction-mode 'mode-motion-handler)
  1966.       (set-mode-motion-handler 'lisp-interaction-mode foo-thing))
  1967.       (or (get 'c-mode 'mode-motion-handler)
  1968.       (set-mode-motion-handler 'c-mode foo-c))
  1969.       (or (get 'c++-mode 'mode-motion-handler)
  1970.       (set-mode-motion-handler 'c++-mode foo-c))
  1971.       (or (get 'c++-c-mode 'mode-motion-handler)
  1972.       (set-mode-motion-handler 'c++-c-mode foo-c))
  1973.       (or (get 'tex-mode 'mode-motion-handler)
  1974.       (set-mode-motion-handler 'tex-mode foo-LaTeX))
  1975.       (or (get 'latex-mode 'mode-motion-handler)
  1976.       (set-mode-motion-handler 'latex-mode foo-LaTeX))
  1977.       (or (get 'Buffer-menu-mode 'mode-motion-handler)
  1978.       (set-mode-motion-handler 'Buffer-menu-mode foo-vline@))
  1979.       (or (get 'Electric-Buffer-menu-mode 'mode-motion-handler)
  1980.       (set-mode-motion-handler 'Electric-Buffer-menu-mode foo-vline@))
  1981.       (or (get 'gnus-Group-mode 'mode-motion-handler)
  1982.       (set-mode-motion-handler 'gnus-Group-mode foo-vline@))
  1983.       (or (get 'gnus-Subject-mode 'mode-motion-handler)
  1984.       (set-mode-motion-handler 'gnus-Subject-mode foo-vline@))
  1985.       (or (get 'gnus-group-mode 'mode-motion-handler)
  1986.       (set-mode-motion-handler 'gnus-group-mode foo-vline@))
  1987.       (or (get 'gnus-subject-mode 'mode-motion-handler)
  1988.       (set-mode-motion-handler 'gnus-subject-mode foo-vline@))
  1989.       (or (get 'gnus-summary-mode 'mode-motion-handler)
  1990.       (set-mode-motion-handler 'gnus-summary-mode foo-vline@))
  1991.       (or (get 'dired-mode 'mode-motion-handler)
  1992.       (set-mode-motion-handler 'dired-mode foo-line@))
  1993.       (or (get 'compilation-mode 'mode-motion-handler)
  1994.       (set-mode-motion-handler 'compilation-mode foo-line@))
  1995.       (or (get 'occur-mode 'mode-motion-handler)
  1996.       (set-mode-motion-handler 'occur-mode foo-line@))
  1997.       (or (get 'tar-mode 'mode-motion-handler)
  1998.       (set-mode-motion-handler 'tar-mode foo-vline@))
  1999.       (or (get 'rmail-summary-mode 'mode-motion-handler)
  2000.       (set-mode-motion-handler 'rmail-summary-mode foo-vline@))
  2001.       (or (get 'vm-summary-mode 'mode-motion-handler)
  2002.       (set-mode-motion-handler 'vm-summary-mode (sect-handler "-line")))
  2003.       (or (get 'tcl-mode 'mode-motion-handler)
  2004.       (set-mode-motion-handler 'tcl-mode (sect-handler "-tcl")))
  2005.       (or (get 'texinfo-mode 'mode-motion-handler)
  2006.       (set-mode-motion-handler 'texinfo-mode (sect-handler "-TeXinfo")))
  2007.       (or (get 'cvs-mode 'mode-motion-handler)
  2008.       (set-mode-motion-handler 'cvs-mode (sect-handler "-cvs-line"))))))
  2009.  
  2010. ;; Null Handlers (for disabling motion highlighting)
  2011. (defun thing-null (here) nil)
  2012. (make-motion-handler 'no-thing 'thing-null)
  2013. (make-motion-handler 'no-c 'thing-null)
  2014. (make-motion-handler 'no-laTeX 'thing-null)
  2015. (make-motion-handler 'no-line 'thing-null)
  2016. (make-motion-handler 'no-line@ 'thing-null)
  2017. (make-motion-handler 'no-vline 'thing-null)
  2018. (make-motion-handler 'no-vline@ 'thing-null)
  2019. (make-motion-handler 'no-tcl 'thing-null)
  2020. (make-motion-handler 'no-TeXinfo 'thing-null)
  2021. (make-motion-handler 'no-cvs-line 'thing-null)
  2022.  
  2023. (defun mode-motion-init ()
  2024.   "enable mode-motion+ package"
  2025.   (interactive)
  2026.  
  2027. (setq mode-motion-last-extent nil)
  2028.   
  2029. (global-set-key '(meta button2) 'mode-motion-copy)
  2030. (global-set-key '(meta shift button2) 'mode-motion-move)
  2031. (global-set-key '(meta control button2) 'mode-motion-kill)
  2032. (global-set-key '(meta control shift button2) 'mode-motion-copy-as-kill)
  2033. (global-set-key '(meta control symbol button2) 'mode-motion-copy-as-kill)
  2034.  
  2035. (if mode-motion-setup-cut-and-paste-bindings
  2036.     (progn 
  2037.       (global-set-key 'f16 'mode-motion-copy-as-kill) ; Copy
  2038.       (global-set-key 'f18 'yank)                  ; Paste
  2039.       (global-set-key 'f20 'mode-motion-kill)))       ; Cut
  2040.  
  2041. ;; I don't want the thing-boundaries function select whitespaces 
  2042. (setq thing-report-whitespace nil thing-report-char-p nil)
  2043.  
  2044. ;; bold motion face (bold, if this is not the default, unbold otherwise)
  2045. (if (find-face 'motion-bold)
  2046.     ()
  2047.   (make-face 'motion-bold)
  2048.   (make-face-bold 'motion-bold)
  2049.   (or (face-differs-from-default-p 'motion-bold)
  2050.       (make-face-unbold 'motion-bold)))
  2051.  
  2052. ;; an underline face
  2053. (if (find-face 'motion-underline)
  2054.     ()
  2055.   (make-face 'motion-underline)
  2056.   (set-face-underline-p 'motion-underline t))
  2057.  
  2058. ;; an inverted face
  2059. (if (find-face 'motion-inverted)
  2060.     ()
  2061.   (make-face 'motion-inverted)
  2062.   (make-face-bold 'motion-inverted)
  2063.   (invert-face 'motion-inverted))
  2064.  
  2065. (if (find-face 'motion-gray)
  2066.     ()
  2067.   (make-face 'motion-gray)
  2068.   (set-face-background-pixmap 'motion-gray "gray1.xbm"))
  2069.  
  2070. ;; Motion Handlers
  2071.  
  2072. ;; Special Minibuffer handler
  2073.  
  2074. (make-motion-handler 'minibuffer 'minibuffer-selection-boundaries 'highlight t nil)
  2075.  
  2076. ;; Things
  2077. (make-motion-handler 'bold-thing 'thing-boundaries 'motion-bold)
  2078. (make-motion-handler 'gray-thing 'thing-boundaries 'motion-gray)
  2079. (make-motion-handler 'highlight-thing 'thing-boundaries 'highlight)
  2080. (make-motion-handler 'invert-thing 'thing-boundaries 'motion-inverted)
  2081. (make-motion-handler 'underline-thing 'thing-boundaries 'motion-underline)
  2082.  
  2083. ;; Lines
  2084. (make-motion-handler 'bold-line 'line-boundaries 'motion-bold)
  2085. (make-motion-handler 'gray-line 'line-boundaries 'motion-gray)
  2086. (make-motion-handler 'highlight-line 'line-boundaries 'highlight)
  2087. (make-motion-handler 'invert-line 'line-boundaries 'motion-inverted)
  2088. (make-motion-handler 'underline-line 'line-boundaries 'motion-underline)
  2089. (make-motion-handler 'bold-line@ 'line-boundaries 'motion-bold t t)
  2090. (make-motion-handler 'gray-line@ 'line-boundaries 'motion-gray nil t)
  2091. (make-motion-handler 'highlight-line@ 'line-boundaries 'highlight nil t)
  2092. (make-motion-handler 'invert-line@ 'line-boundaries 'motion-inverted nil t)
  2093. (make-motion-handler 'underline-line@ 'line-boundaries 'motion-underline nil t)
  2094.  
  2095. ;; Visible text of line
  2096. (make-motion-handler 'bold-vline 'visible-line-boundaries 'motion-bold)
  2097. (make-motion-handler 'gray-vline 'visible-line-boundaries 'motion-gray)
  2098. (make-motion-handler 'highlight-vline 'visible-line-boundaries 'highlight)
  2099. (make-motion-handler 'invert-vline 'visible-line-boundaries 'motion-inverted)
  2100. (make-motion-handler 'underline-vline 'visible-line-boundaries 'motion-underline)
  2101. (make-motion-handler 'bold-vline@ 'visible-line-boundaries 'motion-bold t t)
  2102. (make-motion-handler 'gray-vline@ 'visible-line-boundaries 'motion-gray nil t)
  2103. (make-motion-handler 'highlight-vline@ 'visible-line-boundaries 'highlight nil t)
  2104. (make-motion-handler 'invert-vline@ 'visible-line-boundaries 'motion-inverted nil t)
  2105. (make-motion-handler 'underline-vline@ 'visible-line-boundaries 'motion-underline nil t)
  2106.  
  2107. ;; CVS lines
  2108. (make-motion-handler 'bold-cvs-line 'cvs-line-boundaries 'motion-bold)
  2109. (make-motion-handler 'gray-cvs-line 'cvs-line-boundaries 'motion-gray)
  2110. (make-motion-handler 'highlight-cvs-line 'cvs-line-boundaries 'highlight)
  2111. (make-motion-handler 'invert-cvs-line 'cvs-line-boundaries 'motion-inverted)
  2112. (make-motion-handler
  2113.  'underline-cvs-line 'cvs-line-boundaries 'motion-underline)
  2114.  
  2115. ;; (La)TeX 
  2116. (make-motion-handler 'bold-LaTeX 'latex-boundaries 'motion-bold)
  2117. (make-motion-handler 'gray-LaTeX 'latex-boundaries 'motion-gray)
  2118. (make-motion-handler 'highlight-LaTeX 'latex-boundaries 'highlight)
  2119. (make-motion-handler 'invert-LaTeX 'latex-boundaries 'motion-inverted)
  2120. (make-motion-handler 'underline-LaTeX 'latex-boundaries 'motion-underline)
  2121.  
  2122. ;; TeXinfo
  2123. (make-motion-handler 'bold-TeXinfo 'texinfo-boundaries 'motion-bold)
  2124. (make-motion-handler 'gray-TeXinfo 'texinfo-boundaries 'motion-gray)
  2125. (make-motion-handler 'highlight-TeXinfo 'texinfo-boundaries 'highlight)
  2126. (make-motion-handler 'invert-TeXinfo 'texinfo-boundaries 'motion-inverted)
  2127. (make-motion-handler 'underline-TeXinfo 'texinfo-boundaries 'motion-underline)
  2128.  
  2129. ;; C and C++
  2130. (make-motion-handler 'bold-c 'c-boundaries 'motion-bold)
  2131. (make-motion-handler 'gray-c 'c-boundaries 'motion-gray)
  2132. (make-motion-handler 'highlight-c 'c-boundaries 'highlight)
  2133. (make-motion-handler 'invert-c 'c-boundaries 'motion-inverted)
  2134. (make-motion-handler 'underline-c 'c-boundaries 'motion-underline)
  2135.  
  2136. ;; Tcl/Tk
  2137. (make-motion-handler 'bold-tcl 'tcl-boundaries 'motion-bold)
  2138. (make-motion-handler 'gray-tcl 'tcl-boundaries 'motion-gray)
  2139. (make-motion-handler 'highlight-tcl 'tcl-boundaries 'highlight)
  2140. (make-motion-handler 'invert-tcl 'tcl-boundaries 'motion-inverted)
  2141. (make-motion-handler 'underline-tcl 'tcl-boundaries 'motion-underline)
  2142.  
  2143. ;; mouse tracker
  2144. (make-motion-handler 'track-mouse@ 'char-boundaries nil nil t)
  2145. (make-motion-handler 'highlight-char 'char-boundaries 'highlight)
  2146.  
  2147. ;; augment the basic mouse motion handler (if any)
  2148. (setq-default mode-motion-hook 
  2149.           (if (listp mode-motion-hook)
  2150.           (if (memq #'mode-motion+-highlight mode-motion-hook)
  2151.               mode-motion-hook
  2152.             (append mode-motion-hook (list #'mode-motion+-highlight)))
  2153.         (list mode-motion-hook #'mode-motion+-highlight)))
  2154.  
  2155. (or mode-motion+-religion 
  2156.     (setq mode-motion+-religion (if (x-display-color-p) 'underline 'invert)))
  2157.  
  2158. (add-menu '("Options") (car mode-motion+-options-menu)
  2159.       (cdr mode-motion+-options-menu)
  2160.       "Paren Highlighting")
  2161.  
  2162. ;; shut your eyes, this is a kludge. I didn't have time to find/write
  2163. ;; a function to do this.
  2164. (or (member ["Eval Motion Region" mode-motion-eval-region t]
  2165.         lisp-interaction-popup-menu)
  2166.     (and (setq lisp-interaction-popup-menu
  2167.            (copy-sequence lisp-interaction-popup-menu))
  2168.      (setcdr (nthcdr 1 lisp-interaction-popup-menu)
  2169.          (cons ["Eval Motion Region" mode-motion-eval-region t]
  2170.                (nthcdr 2 lisp-interaction-popup-menu)))))
  2171.  
  2172. (or (member ["Eval Motion Region" mode-motion-eval-region t]
  2173.         emacs-lisp-popup-menu)
  2174.     (and (setq emacs-lisp-popup-menu (copy-sequence emacs-lisp-popup-menu))
  2175.      (setcdr (nthcdr 3 emacs-lisp-popup-menu)
  2176.          (cons ["Eval Motion Region" mode-motion-eval-region t]
  2177.                (nthcdr 4 emacs-lisp-popup-menu)))))
  2178.  
  2179. ;; Clear the last active motion extent when leaving a frame.
  2180. (if (boundp 'mouse-leave-frame-hook)
  2181.     (add-hook 'mouse-leave-frame-hook 'mode-motion-clear-last-extent)
  2182.   (add-hook 'mouse-leave-screen-hook 'mode-motion-clear-last-extent))
  2183.            
  2184. (run-hooks 'mode-motion+-load-hook)
  2185. (mode-motion-init-handlers-according-to-religion)
  2186.  
  2187. (if (interactive-p) (message "mode-motion+ enabled")))
  2188.  
  2189. (if (and (not purify-flag)
  2190.      (or (not (boundp 'opt-mode-motion+)) opt-mode-motion+))
  2191.     (mode-motion-init))
  2192.  
  2193. (provide 'mode-motion+)
  2194. ;; end mode-motion+
  2195.